二十五、继承(二) 不能自动继承的成员函数、继承与构造函数、友元关系与继承、静态成员与继承
2015-01-13 21:23
477 查看
一、不能自动继承的成员函数
有三种函数不能被继承,构造函数,析构函数和=运算符,基类的构造函数和析构函数只负责对基类数据成员的初始化和清理,因为基类并不知道派生类有哪些数据成员。=运算符和构造函数功能类似,所以也不能被继承。
二、继承与构造函数
基类的构造函数不被继承,所以派生类中需要声明自己的构造函数来初始化新增的数据成员。在声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化(调用基类构造函数完成)。为了在派生类中调用基类构造函数,派生类的构造函数需要给基类的构造函数传递参数。在构造派生类的时候,先调用基类的构造函数,在调用派生类的对象函数。
例子:
内存对象模型:
三、友元关系与继承
友元关系不能被继承。友元关系是单向的,是不能传递的,也是不能被继承的。
四、静态成员与继承
静态成无所谓继承。静态成员在内存中的静态存储区,对于类的静态变量来说,即使类没有实例也可以访问其静态变量。如果有实例的话,那么静态变量被所有实例共享。对于基类包含静态成员的派生类来说,基类和派生类共享一块内存,也就是说,基类和派生类共享一个静态变量。
五、需要在初始化列表初始化的情况总结
const成员和引用成员(因为两者都需要在定义的时候初始化,对于类成员来说,初始化只能在构造函数中)
基类的构造(没有默认构造函数的情况下)和组合对象成员(没有默认构造函数的情况下)
对象的构造先调用基类对象成员构造函数,然后调用基类构造函数,接着调用派生类对象成员的构造函数,最后调用派生类的构造函数。析构的顺序和构造正好相反。如果类包含多个对象成员,那么对象成员的构造顺序是和声明顺序相同的。
有三种函数不能被继承,构造函数,析构函数和=运算符,基类的构造函数和析构函数只负责对基类数据成员的初始化和清理,因为基类并不知道派生类有哪些数据成员。=运算符和构造函数功能类似,所以也不能被继承。
二、继承与构造函数
基类的构造函数不被继承,所以派生类中需要声明自己的构造函数来初始化新增的数据成员。在声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化(调用基类构造函数完成)。为了在派生类中调用基类构造函数,派生类的构造函数需要给基类的构造函数传递参数。在构造派生类的时候,先调用基类的构造函数,在调用派生类的对象函数。
例子:
#include <iostream> using namespace std; class ObjectB { public: ObjectB(int objb) : objb_(objb) { cout<<"ObjectB ..."<<endl; } ~ObjectB() { cout<<"~ObjectB ..."<<endl; } int objb_; }; class ObjectD { public: ObjectD(int objd) : objd_(objd) { cout<<"ObjectD ..."<<endl; } ~ObjectD() { cout<<"~ObjectD ..."<<endl; } int objd_; }; class Base { public: Base(int b) : b_(b), objb_(111) { cout<<"Base ..."<<endl; } Base(const Base& other) : objb_(other.objb_), b_(other.b_) { } ~Base() { cout<<"~Base ..."<<endl; } int b_; //对象组合 ObjectB objb_; }; class Derived : public Base { public: Derived(int b, int d) : d_(d), Base(b), objd_(222) { cout<<"Derived ..."<<endl; } Derived(const Derived& other) : d_(other.d_), objd_(other.objd_), Base(other) { } ~Derived() { cout<<"~Derived ..."<<endl; } int d_; ObjectD objd_; }; int main(void) { Derived d(100, 200); cout<<d.b_<<" "<<d.d_<<endl; Base b1(100); Base b2(b1); cout<<b2.b_<<endl; Derived d2(d); return 0; }运行结果:
内存对象模型:
三、友元关系与继承
友元关系不能被继承。友元关系是单向的,是不能传递的,也是不能被继承的。
四、静态成员与继承
静态成无所谓继承。静态成员在内存中的静态存储区,对于类的静态变量来说,即使类没有实例也可以访问其静态变量。如果有实例的话,那么静态变量被所有实例共享。对于基类包含静态成员的派生类来说,基类和派生类共享一块内存,也就是说,基类和派生类共享一个静态变量。
#include <iostream> using namespace std; class Base { public: Base(int t) :b(t){} static void show() { cout<<"Base show"<<endl; } static int a; int b; }; int Base::a = 99; class Derived : public Base { public: Derived(int t):Base(t){} static void show() { cout<<"Derived show"<<endl; } }; int main(void) { Base base(10); Derived d(200); cout<<"static Base::a="<<Base::a<<endl; cout<<"non static Base::b="<<base.b<<endl; cout<<"static Derived::a="<<Derived::a<<endl; cout<<"non static Derived::b="<<d.b<<endl; d.show(); //d.Base::show(); return 0; }结果:
五、需要在初始化列表初始化的情况总结
const成员和引用成员(因为两者都需要在定义的时候初始化,对于类成员来说,初始化只能在构造函数中)
基类的构造(没有默认构造函数的情况下)和组合对象成员(没有默认构造函数的情况下)
对象的构造先调用基类对象成员构造函数,然后调用基类构造函数,接着调用派生类对象成员的构造函数,最后调用派生类的构造函数。析构的顺序和构造正好相反。如果类包含多个对象成员,那么对象成员的构造顺序是和声明顺序相同的。
相关文章推荐
- C++语法基础--恢复继承成员的访问级别,默认继承保护级别,友元关系与继承,继承与静态成员
- 为什么内联函数,构造函数,静态成员函数不能为virtual函数
- PHP手册-静态绑定(继承关系中处理静态成员)
- c++笔记(6):类、对象、构造函数、析构函数、静态成员、友元、类包含
- 在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类?
- C++友元关系和类的静态成员概念和使用
- 一个关于继承关系中静态快、成员变量、构造体代码的执行顺序的Java代码
- C++学习5-面向对象编程基础(构造函数、转换构造、静态数据成员、静态成员函数、友元)
- 为什么内联函数,构造函数,静态成员函数不能为virtual函数
- virtual与构造/析构函数(内联函数,构造函数,静态成员函数不能为virtual函数)
- 友元关系与继承以及基类派生类定义构造函数时应该注意的事项
- 为什么内联函数,构造函数,静态成员函数不能为virtual函数?
- 友元与继承、静态成员与继承
- 为什么内联函数,构造函数,静态成员函数不能为virtual函数
- 为什么内联函数,构造函数,静态成员函数不能为virtual函数
- 为什么内联函数,构造函数,静态成员函数不能为virtual函数
- 为什么内联函数,构造函数,静态成员函数不能为virtual函数?
- JAVA基础:子类、父类继承关系 静态块、非静态块、构造函数初始化顺序性、静态非静态方法覆盖
- 继承(三)--友元与继承&&静态成员与继承
- JAVA继承关系中静态代码块、非静态代码块,构造函数的执行顺序