攀枝花网站开发/免费建站系统哪个好用吗
正确的说法是基类的普通成员函数可以被继承,可以通过派生类的对象访问,类的构造函数、析构函数不能被继承。而我的理解是构造函数被继承了,但它们的名字和派生类的名字是不一样的,不能成为派生类的构造函数,因此我们就要进行显示的调用基类的构造函数对基类继承过来的数据进行初始化。
派生类也是类,那么它的初始化也是调用构造函数来初始化,这时我们就可以定义派生类的构造函数,在里面添加对基类构造函数调用,这样我们就能够对派生类自己添加的数据成员进行初始化的同时,也能对有基类继承过来的数据成员进行初始化,即能对派生类的所有数据进行初始化了。
如下面的例子
-
#include <iostream>
using namespace std;
class A {
public:
A(int a = 0) :x(a) { }//构造函数void s() { cout << "x=" << x << endl; }
private:int x;
};
class D :public A {
public:
D(int a = 0, int b = 0) :A(a), z(b) { }//A(a)调用的是A类的A()这个构造函数,若基类有默认构造函数(有默认参数的构造函数或无参数的构造函数)也可不用显式调用,系统将自动调用基类的默认构造函数,即 D(int a = 0, int b = 0) :z(b) { } 当然如果没有默认构造函数,还不显式调用,那么将编译失败 ,注意类中已经显式定义了构造函数,编译器不会再生成默认的构造函数。void get() {
s();
cout << "z=" << z << endl;
}private:
int z;
};
int main()
{
A b(4); D c(5, 6);
cout << "A类"; b.s();
cout << "D类"<<endl;
c.get();
return EXIT_SUCCESS;}
运行结果为:
A类x=4
D类
x=5
z=6
请注意派生类定义的这一行D(int a = 0, int b = 0) :A(a), z(b) { }调用基类构造函数只能在派生类的参数初始化列表,它们之间以逗号隔开。如
构造函数的调用顺序
#include<iostream>
using namespace std;
class A {
public:A(int a) :x(a)
{
cout << "A" << endl;
}
void getx(){ cout << "x=" <<x<< endl;
}
private:
int x;
};
class B :public A {
public:B(int a) :A(a)
{
cout << "B" << endl;
}
};
class C :public B {
public:C(int s) :B(s){
cout << "C" << endl;
getx();
}
};
int main()
{
C a(6);
}
结果为
A
B
C
x=6
public:C(int s) :B(s)
{
cout << "C" << endl;
getx();
}
//在这时不用显式的调用A的构造函数,因为在调用B类构造函数时,以隐式调用(因为你再显式调用,那将执行两次A类的构造函数,这将浪费资源),就算你显式调用A的构造函数,那程序也将出错,即C++ 禁止在 C 中显式地调用 A 的构造函数。
#include<iostream>
using namespace std;
class A {
int s;
public:
int gets() { return s; }
A(int a) :s(a)
{
cout << "A" << endl;
}
};
class B : virtual public A {
public: B(int a) :A(a)
{
cout << "B" << endl;
}
};
class C : virtual public A {
public:
C(int a) :A(a)
{
cout << "C" << endl;
}
};
class D :public B, public C {
public:D(int a, int b) :A(a), B(b), C(b)//假设B、C类中的构造函数会执行A的构造函数(没被忽略),那A的构造函数将执行三次,那么变量s的值应为b的值,若s不为b的值,那假设不成立
{
cout << "D" << endl;
cout << gets() << endl;
}
};
int main()
{
D a(1, 2);
return 0;
}
运行结果为
A
B
C
D
1//s不为b的值,假设不成立,说明B、C类中的构造函数A的构造函数被忽略
在以上例子中的
public:D(int a, int b) :A(a), B(b), C(b)
{
cout << "D" << endl;
cout << gets() << endl;
}
在这时就要显式的调用A的构造函数, B、C的构造函数中A的构造函数被忽略,保证A类构造函数只执行一次。
原因(个人看法):如果去掉在原来的代码中的"A(a)",如
public:D(int a, int b) :B(b), C(b)
{
cout << "D" << endl;
cout << gets() << endl;
}
那B、C类中的构造函数都会执行A的构造函数,即将执行两次A的构造函数,那么这将浪费资源,如果继承关系更多的话(A->B->C->D->E),那将执行更多次A类的构造函数,那将更浪费资源。
补充
以下是虚基类初始化的定义: