继承与派生是同一过程从不同的角度看
被继承的已有类称为基类(父类)
派生出的新类称为派生类(子类)
直接参与派生出某类的基类称为直接基类
基类的基类甚至更高层的基类称为间接基类
继承的目的是为了实现设计与代码的重用
派生则是因为当新的问题出现,原有程序无法解决时,需要对原有程序进行改造
默认情况下派生类包含了全部基类中除构造和析构函数之外的所有成员(C++11规定可以用using语句继承基类构造函数)
如果派生类声明了一个和某基类成员同名的新成员,派生的新成员就隐藏或覆盖了外层的同名成员
单继承
/*
class 派生类名 : 继承方式 基类名
{
成员声明 ;
}
*/
class Derived :public Base
{
public:
Derived() ;
~Derived() ;
}
多继承
/*
class 派生类名 : 继承方式1 基类名1, 继承方式2 基类名2
{
成员声明 ;
}
每一个继承方式,只用于限制对紧随其后的基类的继承
*/
class Derived :public Base1, private Base2
{
public:
Derived() ;
~Derived() ;
}
不同继承方式的影响主要体现在:
三种继承方式:
默认情况下
(C++11中,可以使用using语句继承基类构造函数,但只能初始化从基类继承的成员,语法形式using B::B
)
单继承
#include <iostream>
using namespace std;
class B {
public:
B();
B(int i);
~B();
void print() const;
private:
int b;
};
B::B() {
b = 0;
cout << "B‘s default constructor called" << endl;
}
B::~B() {
cout << "B‘s destructor called" << endl;
}
B::B(int i) {
b = i;
cout << "B‘s constructor called" << endl;
}
void B::print() const {
cout << b << endl;
}
class C :public B {
public:
C();
C(int i, int j);
~C();
void print() const;
private:
int c;
};
C::C() {
c = 0;
cout << "C‘s default constructor called" << endl;
}
C::C(int i, int j) : B(i), c(j) {
cout << "C‘s constructor called" << endl;
}
C::~C() {
cout << "C‘s destructor called" << endl;
}
void C::print() const {
B::print();
cout << c << endl;
}
int main() {
C c(2, 3);
c.print();
return 0;
}
/*
B‘s constructor called
C‘s constructor called
2
3
C‘s destructor called
B‘s destructor called
*/
多继承
#include <iostream>
using namespace std;
class Base1 {
public:
Base1(int i) {
cout << "Constructing Base1 " << i << endl;
}
};
class Base2 {
public:
Base2(int j) {
cout << "Constructing Base2 " << j << endl;
}
};
class Base3 {
public:
Base3() {
cout << "Constructing Base3" << endl;
}
};
/*
先按照继承的顺序,对继承过来的成员调用基类的构造函数进行初始化
然后给派生类的新增成员进行初始化 member1, member2, member3
*/
class Derived : public Base2, public Base1, public Base3 {
public:
Derived(int a, int b, int c, int d) : Base1(a), Base2(b), member2(c), member1(d) {}
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 4
Constructing Base2 3
Constructing Base3
*/
若派生类没有声明复制构造函数:
若派生类定义复制构造函数
一般都要为基类的复制构造函数传递参数
复制构造函数只能接受一个参数,既用来初始化派生类定义的成员,也将被传递给基类的复制构造函数
基类的复制构造函数形参类型是基类对象的引用,实参可以是派生类对象的引用
C::C(const C & c1): B(c1) ...{ ... }
当派生类与基类中有相同成员时:
二义性问题
如果从不同基类继承了同名成员,但是在派生类中没有定义同名成员,就产生二义性问题
解决方式:用类名限定
当派生类从多个基类派生,而这些基类又有一个共同的基类,则在访问此共同基类中的成员时,将产生冗余,虚基类就是用于解决这一问题
class B1 : virtual public B ......
虚基类的作用:
虚基类的构造函数:
#include <iostream>
using namespace std;
class Base0 {
public:
int var0;
Base0(int var) : var0(var) {}
void fun0() {
cout << "Member of Base0" << endl;
}
};
class Base1 : virtual public Base0 {
public:
Base1(int var) : Base0(var), var1(var) {}
int var1;
};
class Base2 : virtual public Base0 {
public:
Base2(int var) : Base0(var), var2(var) {}
int var2;
};
class Derived : public Base2, public Base1{
public:
Derived(int var) : Base0(var), Base1(var), Base2(var) {}
};
int main() {
Derived obj(1);
cout << obj.var0 << endl;
return 0;
}
/*
1
*/
原文:https://www.cnblogs.com/Suans/p/14489884.html