调用完构造函数的顺序 :基类 子类 子子类
不仅构造函数 析构函数也这样 子类对象析构时自动调用基类的析构函数
顺序与构造函数顺序相反 :子类基类
关于显示调用基类的构造函数,是不可行的。必须用初始化表的形式调用基类构造函数,才能正确的把子类继承下来的父类的成员初始化了。如果在子类构造函数体内显式调用了基类构造函数的话,那么该构造函数就会对一个在子类构造函数内存空间内的一个临时对象进行了初始化,因为没有取得正确的对象(子类对象)的指针。所以构造了半天白费。等子类构造函数退出,则统统丢失。所以,基类构造函数在没拿到正确this指针的情况下,没有办法正确赋值。下面是例子:
#include <iostream>
#include<string>
using namespace std;
class CLSA{
public:
CLSA( )
{}
CLSA( int i ) : m_j(i) {}
int getA()
{return m_j;}
private:
int m_j;
};
class CLS: public CLSA
{
public:
CLS( int i,int j );
/CLS()
{
CLS(0);
}/
int m_i;
};
CLS::CLS( int i,int j ) : m_i(i) ,CLSA(j)
{
CLSA(10);//这里显式调用基类构造函数给临时对象进行赋值的,但是等CLS构造函数退出返回后,临时对象丢失。所以, 这个函数没有给真正的对象赋值。因为没有取得正确的this地址。
}
int main()
{
CLS obj(2,3);
cout << objm_i << endl; //输出结果是什么?CLSA(j),
cout<<objgetA();
return 0;
}
派生类的构造函数后于基类构造函数被调用,用于派生类对象被创建时自动完成初始化派生类自身的成员和申请系统资源的工作。
派生类的析构函数先于基类析构函数被调用,用于在派生类对象的生命周期结束时,自动释放派生类对象所占的系统资源。
派生类构造函数不但要初始化派生类中新增数据成员,还要负责基类数据成员的初始化。在建立派生类对象时,执行构造函数的顺序是:1、派生类构造函数先调用基类构造函数;2、再执行派生类构造函数本身。析构函数的执行顺序则相反。
瞧你这话说得!!
子类从基类继承来的变量在基类构造函数中可以初始化,在子类构造函数中也可以初始化!
在子类构造对象时,首先要调用基类的构造函数,再调用子类的构造函数;
子类对继承来的变量:
1初始化:那么可想而知,最终构造子类对象时子类对这个变量的初始化起了作用(因为先基类构造函数对其初始化,后子类构造函数对其初始化,明白吧);
2不初始化:那么可想而知,子类不干初始化这变量的事了,所以基类构造函数的初始化就发挥了作用。
总之,一句话,记住构造子类对象时,构造函数调用的顺序:始终是先调用基类构造函数,再调用子类构造函数,其他衍生出来的问题仔细想想就明白了!!
如果解决了你的疑惑,请采纳!否则请追问!加油哦!
那个不叫兼容性,那是把派生类的对象当做基类的对象来使用。
公有继承: 派生类在任何地方都可以作为基类使用。
保护继承: 派生类只可以在派生类成员函数、孙子类成员函数和友元函数内当做基类对象使用。
私有继承: 派生类只能在派生类本身的成员函数以及友元函数内当做基类对象使用。
C::C(C &c1):B(c1){…}
这段代码定义了派生类的拷贝构造函数, 然后调用了基类的拷贝构造函数(c1被当做基类B的对象来使用)。
#include <iostream>class Base {
public:
Base() {
std::cout << "Base()" << std::endl;
}
Base(const Base & other) {
std::cout << "Base(const Base &)" << std::endl;
}
};
class Derived : private Base {
public:
Derived() {
std::cout << "Derived()" << std::endl;
}
Derived(const Derived & other) : Base(other) {
std::cout << "Derived(const Derived &)" << std::endl;
}
};
int main() {
Derived d1;
auto d2 = d1;
system("pause");
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)