先看继承类的测试代码
#include<iostream>
using namespace std;
class A
{
public:
A()
{
cout << "A Constructor!" <<" Address :"<< this << endl;
}
A(int i)
{
cout << "A Constructor with Para!"<<" Address :"<< this <<endl;
}
A(const A &a)
{
cout << "A Copy Constructor" <<" Address:" << this << endl;
}
A &operator = (const A &a)
{
cout << "A euqal Constructor" <<" Address:" << this << endl;
return *this;
}
virtual ~A()
{
cout << "A Destructor!" <<" Address :"<< this <<endl;
}
virtual void test()
{
cout << "A test() with virtual"<<endl;
}
void test1()
{
cout << "A test1() without virtual"<<endl;
}
};
class B : public A
{
public:
B()
{
cout << "B Constructor!"<<" Address :"<< this << endl;
}
B(int i) : A(i) //如果不加:A(i),那么在主函数中B b(2);的时候,先调用A(),在调用B(int i)。
{
cout << "B Constructor with Para!"<<" Address :"<< this <<endl;
}
B(const B &a)
{
cout << "B Copy Constructor" <<" Address: " << this << endl;
}
B &operator = (const B &a)
{
cout << "B euqal Constructor" <<" Address: " << this << endl;
return *this;
}
~B()
{
cout << "B Destructor!" <<" Address :"<< this <<endl;
}
void test()
{
cout << "B test() with virtua"<<endl;
}
void test1()
{
cout << "B test1() without virtual"<<endl;
}
};
int main()
{
B b,b1(2);
A a;
a = (A)b; //对象强制转换的时候,先生成一个b的拷贝(此处用到拷贝构造函数),相当于函数的形参,然后调用赋值构造函数,然后将拷贝删除
a = b; //直接调用赋值构造函数
a.test(); //对象,调用的是A的test
a.test1(); //调用的是a的test1
A *a1 = &b;
a1->test(); //指针,调用的是B的test,虚函数
a1->test1();//指针,调用的是A的test1,普通函数
A &a2 = b;
a2.test(); //引用,调用的是B的test,虚函数
a2.test1(); //指针,调用的是A的test1,普通函数
B b3 = b; //调用A的构造函数和B的拷贝构造函数
a1 = (A *)&b1; //指针强制转换没有调用拷贝构造函数及赋值构造函数
B *b2 = new B(); //在堆中分配的内存,在离开其作用域的时候不会自动释放,必须手动删除
A *a3 = b2;
delete a3; //此处,如果A的析构函数没有加virtual,那么在delete a的时候,只会调用A的析构函数。而不会调用B的析构函数,造成内存溢出
return 1;
//最后在主函数结束的时候,可以看到,析构的顺序是 a,b1,b。 与创建对象的顺序相反,也就是先进后出,栈的数据结构。着也说明了在函数中的变量是存放在栈区的。
}
测试结果如下图:
分析部分见上面代码中的注释!
下面是单类构造函数的例子:
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "A Constructor!" <<" Address :"<< this << endl;
}
A(int i) //单个参数的构造函数如果不添加explicit(显示的)关键字,会定义一个隐含的类型转换(从参数的类型转换到自己的);添加explicit可以消除这种隐式转换
{
cout << "A Constructor with Para!"<<" Address :"<< this <<endl;
}
A(const A &a)
{
cout << "A Copy Constructor" <<" Address:" << this << endl;
}
A &operator = (const A &a)
{
cout << "A euqal Constructor" <<" Address:" << this << endl;
return *this;
}
~A()
{
cout << "A Destructor!" <<" Address :"<< this <<endl;
}
};
A Play(A a)
{
return a;
} //在函数结束时候,先调用拷贝构造函数将形参拷贝一份,再释放形参的对象
int main()
{
A temp = Play(4); //首先,调用了一个带参数的构造函数,将4通过隐含的类型转换,调用了A::A(int i);
A temp2;
temp2 = temp; //调用赋值构造函数
A temp3 = temp; //调用拷贝构造函数
A temp4 = 5; //调用带参数的构造函数,单个参数的构造函数如果不添加explicit(显示的)关键字,会定义一个隐含的类型转换(从参数的类型转换到自己的);添加explicit可以消除这种隐式转换
return 1;
} //结束的时候,依次先释放temp3,再释放temp2,再释放temp
测试结果如下(分析过程见上面的注释):