1.基类的private成员 (1)无论是哪种继承方式,基类的私有成员都是只有基类的成员函数和其友元才能访问。 (2)派生类的成员函数不能访问基类的private成员。 (3)派生类的对象也不能访问基类的private成员。 2. 基类的public和protected成员 根据派生类的继承方式决定该成员在派生类中的访问级别。
#include <iostream> using namespace std; class Person{ private: int age; char sex; public: Person(int age = 0, char sex = 'm'):age(age), sex(sex){} void print1(){ cout << "age=" << age << endl; cout << "sex=" << sex << endl; } }; class Student:public Person{ private: //int Person::private::age; //char Person::private::sex; int score; int num; public: Student()/*调用基类默认构造*/{} Student(int score, int num):score(score), num(num){} void print(){ // cout << "age=" << age << endl;//error: ‘int Person::age’ is private //cout << "sex=" << sex << endl;//error: ‘char Person::sex’ is private cout << "score=" << score << endl; cout << "num=" << num << endl; } }; int main(void){ Person p1(18, 'm'); Student stu1(99, 12345); p1.print1(); stu1.print1();//子类可以调用父类方法 stu1.print(); cout << sizeof(p1) << endl;//8 cout << sizeof(stu1)<< endl;//16 return 0; }static成员是基类和派生类共享的,有作用域的全局变量,只有一个。若static成员在基类中为private,则派生类不能访问它。
#include <iostream> using namespace std; class Base{ public: static int i; // int i; Base() { cout << "Base构造" << endl; i++; } }; int Base::i=0; class Derived:public Base{ public: //static int Base::public::i; public: Derived() { cout << "Derived构造" << endl; i++; } }; int main(void) { // Base a; // Base *p = new Base; Derived d;//调用基类的构造函数,再调用本类的构造函数 // cout<<Base::i<<endl; // cout<<a.i<<endl; // cout<<p->i<<endl; cout<<d.i<<endl; // cout<<Derived::i<<endl; return 0; }执行结果:
[root@ifc3omk6i0e7ht2z C++]# ./a.out Base构造 Derived构造 2派生类对象包含基类内嵌对象,可以将基类指针指向派生类对象,也可以将基类引用绑定到派生类对象,反过来不行。
Derived d; Base *pb = &d; //基类--->派生类,pb指向派生类对象d中的内嵌基类部分,访问方式是一个Base所占空间的范围 Base &rb = d;//基类 别名 派生类,rb与派生类对象d中基类子对象绑定1.基类指针指向派生类对象,(取上面Person类和Student类的代码),可行 stu1的内存地址
&stu1.num: 0x7ffe3462225c &stu1.score: 0x7ffe34622258 &stu1.sex: 0x7ffe34622254 &stu1.age: 0x7ffe34622250 &stu1: 0x7ffe346222502.派生类指针指向基类对象,不可行,编译报错。
Person per1; Student *p = &per1;//编译报错,invalid conversion from ‘Person*’ to ‘Student*’ [-fpermissive]派生类对象由派生类新增的成员加上一个或者多个基类的子对象构成,当构造,复制,赋值和析构派生类的对象时,也需要构造,复制,赋值和析构(派生类的析构函数不负责撤消基类对象的成员,编译器会调用基类的析构函数来做基类成员的清理工作)这些基类子对象(从基类继承过来的数据成员)。 派生类对象的构造顺序:
调用基类的构造函数再调用对象成员类(内嵌对象)的构造函数最后执行派生类构造函数的函数体。 class Person{ private: int age; char sex; public: Person(){cout << "Person 默认构造" << endl;}; Person(int age, char sex = 'm'):age(age), sex(sex){} } class Student:public Person{ private: //int Person::private::age; //char Person::private::sex; int score; int num; Person ps; public: Student():Person()/*调用基类默认构造*/,ps()/*调用(内嵌对象)的构造函数*/{/*执行派生类构造函数的函数体*/} }派生类对象的复制控制: 如果 派生类显式定义了自己的复制控制函数,则会完全覆盖默认的定义,即此时派生类的复制控制函数-----要负责派生类新增成员的复制控制,同时也要负责对基类成员的复制或者赋值。
#include <iostream> #include <string.h> using namespace std; class Person{ private: char sex; protected: int age; char *name; public: //默认构造 Person(int age = 0, char *name = NULL):age(age){ if (name == NULL){ this->name = NULL; }else{ this->name = new char[strlen(name) + 1]; strcpy(this->name, name); } cout << this << " Person 构造" << endl; } //复制构造 Person(const Person & other):age(other.age){ if (other.name == NULL){ name = NULL; }else{ name = new char[strlen(other.name) + 1]; strcpy(name, other.name); } cout << this << " Person 复制构造" << endl; } //赋值运算符重载 Person& operator= (const Person &other){ age = other.age; delete[] name; if (other.name == NULL){ name == NULL; }else{ name = new char[strlen(other.name) + 1]; strcpy(name, other.name); } cout << this << " Person 赋值运算符重载" << endl; } ~Person(){ delete[] name; cout << this << " Person 析构" << endl; } void ps_print(){ cout << "姓名:" << name << endl; cout << "年龄:" << age << endl; } }; class Student:protected Person{ private: int num; int score; char *school; Person ps; public: Student (int num = 0, int score = 0, char *school = NULL) :Person(18, (char *)"继承者"), num(num), score(score), ps(5, (char *)"内嵌基类对象"){ if (school == NULL){ this->school = NULL; }else{ this->school = new char[strlen(school) + 1]; strcpy(this->school, school); } cout << this << " Student 构造" << endl; } //复制构造 Student(const Student & other):Person(other)/*继承复制构造*/,ps(other.ps)/*内嵌对象构造*/{ num = other.num; score = other.score; if (other.school == NULL){ school = NULL; }else{ school = new char[strlen(other.school) + 1]; strcpy(school, other.school); } // ps = other.ps; cout << this << " Student 复制构造" << endl; } //赋值运算符重载 Student& operator= (const Student &other){ /*********关键****************/ //调用基类的赋值运算符重载,给从基类继承过来的子对象部分赋值 Person::operator = (other); /***************************/ num = other.num; score = other.score; delete[] school; if (other.school == NULL){ school = NULL; }else{ school = new char[strlen(other.school) + 1]; strcpy(school, other.school); } ps = other.ps; cout << this << " Student 赋值运算符重载" << endl; } ~Student(){ delete[] school; cout << this << " Student 析构" << endl; } void stu_print(){ cout << "---------继承者信息-------------" << endl; ps_print(); cout << "学校:" << school << endl; cout << "学号:" << num << endl; cout << "-------------------------------" << endl; cout << "--------内嵌基类对象信息-------" << endl; ps.ps_print(); cout << "-------------------------------" << endl; } }; int main(void){ Person ps1(18, (char *)"王五"); ps1.ps_print(); Student stu1(123456, 99, (char *)"布村寨大学"); stu1.stu_print(); return 0; }运行结果
0x7ffef8217120 Person 构造 姓名:王五 年龄:18 0x7ffef82170f0 Person 构造 0x7ffef8217110 Person 构造 0x7ffef82170f0 Student 构造 ---------继承者信息------------- 姓名:继承者 年龄:18 学校:布村寨大学 学号:123456 ------------------------------- --------内嵌基类对象信息------- 姓名:内嵌基类对象 年龄:5 ------------------------------- 0x7ffef82170f0 Student 析构 0x7ffef8217110 Person 析构 0x7ffef82170f0 Person 析构 0x7ffef8217120 Person 析构