您的位置:首页 > 其它

二十五、继承(二) 不能自动继承的成员函数、继承与构造函数、友元关系与继承、静态成员与继承

2015-01-13 21:23 477 查看
一、不能自动继承的成员函数
          有三种函数不能被继承,构造函数,析构函数和=运算符,基类的构造函数和析构函数只负责对基类数据成员的初始化和清理,因为基类并不知道派生类有哪些数据成员。=运算符和构造函数功能类似,所以也不能被继承。
二、继承与构造函数

          基类的构造函数不被继承,所以派生类中需要声明自己的构造函数来初始化新增的数据成员。在声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化(调用基类构造函数完成)。为了在派生类中调用基类构造函数,派生类的构造函数需要给基类的构造函数传递参数。在构造派生类的时候,先调用基类的构造函数,在调用派生类的对象函数。
例子:
#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成员和引用成员(因为两者都需要在定义的时候初始化,对于类成员来说,初始化只能在构造函数中)
基类的构造(没有默认构造函数的情况下)和组合对象成员(没有默认构造函数的情况下)

          对象的构造先调用基类对象成员构造函数,然后调用基类构造函数,接着调用派生类对象成员的构造函数,最后调用派生类的构造函数。析构的顺序和构造正好相反。如果类包含多个对象成员,那么对象成员的构造顺序是和声明顺序相同的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐