派生类的声明
单继承时
class 派生类名:继承方式 基类名
{
成员声明;
}
继承方式:public protected private
公有继承(public):
- 基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可直接访问。
- 派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
- 派生类的对象只能访问基类的public成员。
-
#include<iostream> using namespace std; class Point { //基类Point类的定义 public: //公有函数成员 void initPoint(float x = 0, float y = 0) { this->x = x; this->y = y;} void show( ) { cout<<x<<","<<y<<endl; } private: //私有数据成员 float x, y; }; class Circle: public Point {//派生类定义部分 public: //新增公有函数成员 void initCircle(float x, float y, float r1) { initPoint(x, y); //调用基类公有成员函数 this->r = r1; } private: //新增私有数据成员 float r; }; int main() { Circle c1; //定义Circle类的对象 c1.initCircle(2, 3, 20);//设置圆的数据 c1.show( ); //派生类对象访问基类公有成员 return 0; }
私有继承(private):
- 派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
- 通过派生类的对象不能直接访问基类中的任何成员。
保护继承(protected)
- 派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
- 通过派生类的对象不能直接访问基类中的任何成员
类型转换规则
一个公有派生类的对象在使用上可以被当作基类的对象,反之则禁止。具体表现在:
▫ 派生类的对象可以隐含转换为基类对象。
▫ 派生类的对象可以初始化基类的引用。
▫ 派生类的指针可以隐含转换为基类的指针。
基类对象名、指针只能访问从基类继承的成员
#include<iostream>
using namespace std;
class Base { //基类Base定义
public:
void display() const {
cout << "Base::display()" << endl;
}
};
//公有派生类Derived定义
class Derived: public Base {
public:
void display() const {
cout << "Derived::display()"<<endl;
}
};
void fun(Base *ptr) { //参数为指向基类对象的指针
ptr->display(); //"对象指针->成员名"
}
int main() { //主函数
Base base; //声明Base类对象
Derived derived; //声明Derived类对象
fun(&base); //用Base对象的指针调用函数
fun(&derived); //用Derived对象的指针调用函数
return 0;
}
单一继承时的构造函数
- 基类的构造函数不被继承,派生类中需要声明自己的构造函数。
- 定义构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化,自动调用基类构造函数完成。
- 派生类的构造函数需要给基类的构造函数传递参数
#include<iostream>
using namespace std;
class B {
public:
B(int i) {
b=i; cout<<"B's constructor called."<<endl;
}
~B(){ cout<<"B's destructor called."<<endl; }
void print() const{ cout<<b<<endl; }
private:
int b;
};
class C: public B {
public:
C(int i,int j): B(i), c(j){
cout<<"C's constructor called." << endl;
}
~C(){ cout<<"C's destructor called." << endl; }
void print() const { B::print(); cout<<c<<endl;}
private:
int c;
};
int main() {
C obj(5, 6);
obj.print();
return 0;
}
构造函数的执行顺序
1.调用基类构造函数,调用顺序按照它们被继承时声明的顺序(从左向右)。
2. 对本类成员初始化列表中的基本类型成员和对象成员进行初始化,初始化顺序按照它们在类中声明的顺序。对象成员初始化是自动调用对象所属类的构造函数完成的。
3. 执行派生类的构造函数体中的内容
#include<iostream>
using namespace std;
class Base1 { //基类Base1构造函数有参数
public:
Base1(int i) { cout<<"Constructing Base1 "<<i<<endl;}
};
class Base2 { //基类Base2构造函数无参数
public:
Base2( ) { cout<<"Constructing Base2 *"<<endl;}
};//派生新类Derived,注意基类名的顺序
class Derived:public Base2,public Base1{
public:
Derived(int a,int b):Base1(a){ c=b;}
private:
int c;
};
int main() {
Derived obj(1, 2);
return 0;
}
一道综合题
#include <iostream>
using namespace std;
class Base1 { //基类Base1,构造函数有参数
public:
Base1(int i) { cout << "Constructing Base1 " << i << endl; }
~Base1() { cout << "Destructing Base1" << endl; }
};
class Base2 { //基类Base2,构造函数有参数
public:
Base2(int j) { cout << "Constructing Base2 " << j << endl; }
~Base2() { cout << "Destructing Base2" << endl; }
};
class Base3 { //基类Base3,构造函数无参数
public:
Base3() { cout << "Constructing Base3 *" << endl; }
~Base3() { cout << "Destructing Base3" << endl; }
};
class Derived: public Base2, public Base1, public Base3 {
//派生新类Derived,注意基类名的顺序
public: //派生类的公有成员
Derived(int a, int b, int c, int d): Base1(a), member2(d),
member1(c), Base2(b) { }
//注意基类名的个数与顺序,注意成员对象名的个数与顺序
private: //派生类的私有成员对象
Base1 member1;
Base2 member2;
Base3 member3;
};
int main() {
Derived obj(1, 2, 3, 4);
return 0;
}
运行结果
Constructing Base2 2
Constructing Base1 1
Constructing Base3 *
Constructing Base1 3
Constructing Base2 4
Constructing Base3 *
Destructing Base3
Destructing Base2
Destructing Base1
Destructing Base3
Destructing Base1
Destructing Base2--------------------------------
Process exited after 0.04467 seconds with return value 0
请按任意键继续. . .