在定义类的时候,会遇到基类的构造函数带参数,而子类子类构造函数不带参数,这时候如果以代码 a 的方式建立派生类则会出错。
代码 a:
class A
{
public:
A(int x, int y):i(x),j(y){ }
private:
int i, j;
};
class B:public A
{
public:
B() { cout << "init B" << endl; }
};
在建立B类对象时,编译出错:
error C2512: ‘A’ : no appropriate default constructor available
解决这个问题应该在A的构造函数中显式调用基类的带参构造函数。因为在基类中定义了带参构造函数,编译器不会提供默认构造函数。(或者可以在基类中增加一个不带参数的构造函数)这个问题将解决。
代码 b 采用的是调用基类带参构造函数的方式:
代码 b:
class A
{
public:
A(int x, int y) :i(x),j(y){ }
private:
int i, j;
};
class B:public A
{
public:
B():A(10,20) { cout << "init B" << endl; }
};
//即在构造函数的后面增加一个冒号,后面是基类的构造函数。这种方式同样可以用来初始化类中的常量(初始化列表)。
通过在基类中增加一个不带参数的构造函数:
代码 c:
class A
{
public:
A(int x, int y):i(x),j(y){ }
A(); //不带参数的构造函数
private:
int i, j;
};
class B:public A
{
public:
B():A(10,20) { cout << "init B" << endl; }
};
#include <iostream>
using namespace std;
/*有时,基类存在重载的构造函数,而搞造函数对类的数据成员进行了初始化,
* 这种情况下,在继承基类时,需要对基类的数据成员进行初始化 /
class Person
{
protected: //只能在派生类内部访问protected成员,外部不可访问
bool man;
public:
void CheckPerson()
{
if (man)
cout << "Person is man" << endl;
else
cout << "Person is woman" << endl;
}
Person(bool initValue)
{ //构造函数的重载,带初始值
man = initValue;
cout << "Person constructor" << endl;
}
~Person()
{
cout << "~Person deconstructor" << endl;
}
};
class Man: public Person
{ //public继承,可访问基类public和protected权限的成员
public:
Man() : Person(true) {}; //利用初始化列表,对基类的成员进行初始化(基类重载构造函数需要初始化值)
~Man() {};
};
int main()
{
Man Tom;
Tom.CheckPerson(); //4:派生类外部可调用继承的基类public成员
//Tom.man = false; //编译出错,外部不可修改继承的protected成员
return 0;
}
综合例子:
#include <iostream>
using namespace std;
class A {
public:
A(int ii):i(ii)
{
cout<<"A::A()"<<endl;
}
~A()
{
cout<<"A::~A()"<<endl;
}
void print()
{
cout<<"A::print() "<<i<<endl;
}
void print(int i)
{
cout<<"now i ="<<i<<endl;
print();
}
void set(int ii)
{
i = ii;
cout<<"set("<<i<<")"<<endl;
}
private:
int i;
};
class B : public A {
public:
B(int a):A(15),t(a)
{ //父类构造函数有参数,子类构造的时候需对父类进行初始化
cout<<"B::B()"<<endl;
}
~B()
{
cout<<"B::~B()"<<endl;
}
void print()
{
cout<<"B::print()"<<endl;
}
void f()
{
cout<<t<<endl;
set(20);
//i = 10; error: public继承不能直接修改基类里的private成员
print();
}
private:
int t;
}; //public继承,可以访问,不能直接修改基类里的private成员.
int main()
{
B b(1000);
b.f();
b.print();
b.set(10);
cout<<"test beginning!"<<endl;
b.print();
b.f();
b.A::print(200); //C++在父类和子类同时定义了一个函数名和参数表都一样的时候,只有子类一个函数,父类的同名函数全部被隐藏
cout<<"test over!"<<endl;
return 0;
}