目录
为什么要使用继承
继承的概念
派生类定义方法
派生类访问权限控制
继承中的析构和构造
继承中的对象模型
对象构造和析构的调用原则
子类和父类同名成员的处理方法
非自动继承的函数
静态成员在继承中的特点
多继承
多继承概念
菱形继承和虚继承
虚继承实现原理
一个类继承另一个类,这样类中可以少定义一些成员
如果直接定于职工类 代码重复比较严重
Class 派生类名 : 继承方式 基类名 {//派生类新增的数据成员和成员函数}
#include
#include
using namespace std;
class Animal
{
public:
int age;
void printf()
{
cout << age << endl;
}
};
class Dog : public Animal
{
public:
int tail_len;
/*相当于拷贝代码
int age;
void printf()
{
cout << << endl;
}
*/
};
void test01()
{
Dog d;
d.age = 10;
d.printf();
}
//基类
class A{
public:
int mA;
protected:
int mB;
private:
int mC;
};
//1. 公有(public)继承
class B : public A{
public:
void PrintB(){
cout << mA << endl; //可访问基类 public 属性
cout << mB << endl; //可访问基类 protected 属性
//cout << mC << endl; //不可访问基类 private 属性
}
};
class SubB : public B{
void PrintSubB(){
cout << mA << endl; //可访问基类 public 属性
cout << mB << endl; //可访问基类 protected 属性
//cout << mC << endl; //不可访问基类 private 属性
}
};
void test01(){
B b;
cout << b.mA << endl; //可访问基类 public 属性
//cout << b.mB << endl; //不可访问基类 protected 属性
//cout << b.mC << endl; //不可访问基类 private 属性
}
//2. 私有(private)继承
class C : private A{
public:
void PrintC(){
cout << mA << endl; //可访问基类 public 属性
cout << mB << endl; //可访问基类 protected 属性
//cout << mC << endl; //不可访问基类 private 属性
}
};
class SubC : public C{
void PrintSubC(){
//cout << mA << endl; //不可访问基类 public 属性
//cout << mB << endl; //不可访问基类 protected 属性
//cout << mC << endl; //不可访问基类 private 属性
}
};
void test02(){
C c;
//cout << c.mA << endl; //不可访问基类 public 属性
//cout << c.mB << endl; //不可访问基类 protected 属性
//cout << c.mC << endl; //不可访问基类 private 属性
}
//3. 保护(protected)继承
class D : protected A{
public:
void PrintD(){
cout << mA << endl; //可访问基类 public 属性
cout << mB << endl; //可访问基类 protected 属性
//cout << mC << endl; //不可访问基类 private 属性
}
};
class SubD : public D{
void PrintD(){
cout << mA << endl; //可访问基类 public 属性
cout << mB << endl; //可访问基类 protected 属性
//cout << mC << endl; //不可访问基类 private 属性
}
};
void test03(){
D d;
//cout << d.mA << endl; //不可访问基类 public 属性
//cout << d.mB << endl; //不可访问基类 protected 属性
//cout << d.mC << endl; //不可访问基类 private 属性
}
#include
using namespace std;
class Aclass
{
public:
int mA;
int mB;
};
class Bclass : public Aclass
{
public:
int mC;
};
class Cclass : public Bclass
{
public:
int mD;
};
void test()
{
cout << "A size:" << sizeof(Aclass) << endl;
cout << "B size:" << sizeof(Bclass) << endl;
cout << "C size:" << sizeof(Cclass) << endl;
}
int main()
{
test();
return 0;
}
编译运行
#include
using namespace std;
class Base
{
public:
Base(int age,string name)
{
this->age = age;
this->name = name;
cout << "Base构造函数" << endl;
}
~Base()
{
cout << "Base析构函数" << endl;
}
int age;
string name;
};
//创建子类对象时,必须先构造父类 需要调用父类的构造函数
class Son:public Base
{
public:
Son(int id,int age,string name):Base(age,name)
{
this->id = id;
cout << "Son构造函数" << endl;
}
~Son()
{
cout << "Son析构函数" << endl;
}
int id;
};
void test()
{
Son p(10,8,"lucy");
}
int main()
{
test();
return 0;
}
编译运行
建的时候先建在里边的父类 再建外边的子类 拆的时候先拆外边的子类 再拆里边的父类 很好理解
如果子类和父类由同名的成员变量,父类的变量会被隐藏,访问的是子类变量
如果子类和父类由同名的成员函数,父类的函数会被隐藏,访问的是子类函数
#include
using namespace std;
class Base
{
public:
Base(int a)
{
}
int a;
};
class Son:public Base
{
public:
Son(int a1,int a2):Base(a1),a(a2)
{
}
int a;
};
void test()
{
Son p(10,20);
cout << p.a << endl;//输出20
}
int main()
{
test();
return 0;
}
class Base{
public:
static int getNum()
{
return sNum;
}
static int getNum(int param)
{
return sNum + param;
}
public:
static int sNum;
};
int Base::sNum = 10;
class Derived : public Base
{
public:
static int sNum; //基类静态成员属性将被隐藏
#if 0
//重定义一个函数,基类中重载的函数被隐藏
static int getNum(int param1, int param2)
{
return sNum + param1 + param2;
}
#else
//改变基类函数的某个特征,返回值或者参数个数,将会隐藏基类重载的函数
static void getNum(int param1, int param2)
{
cout << sNum + param1 + param2 << endl;
}
#endif
};
int Derived::sNum = 20
一个类继承了多个类
#include
using namespace std;
class A
{
public:
int a;
};
class B
{
public:
int a;
};
class C:public A,public B
{
public:
int a;
};
void test()
{
C c;
c.a = 10;
c.A::a= 20;
c.B::a = 30;
}
int main()
{
test();
return 0;
}
#include
using namespace std;
class BigBase{
public:
BigBase(){ mParam = 0; }
void func(){ cout << "BigBase::func" << endl; }
public:
int mParam;
};
class Base1 : public BigBase{};
class Base2 : public BigBase{};
class Derived : public Base1, public Base2{};
int main(){
Derived derived;
//1. 对“func”的访问不明确
//derived.func();
//cout << derived.mParam << endl;
cout << "derived.Base1::mParam:" << derived.Base1::mParam << endl;
cout << "derived.Base2::mParam:" << derived.Base2::mParam << endl;
//2. 重复继承
cout << "Derived size:" << sizeof(Derived) << endl; //8
return 0;
}
#include
using namespace std;
class BigBase{
public:
BigBase(){ mParam = 0; }
void func(){ cout << "BigBase::func" << endl; }
public:
int mParam;
};
class Base1 : virtual public BigBase{};
class Base2 : virtual public BigBase{};
class Derived : public Base1, public Base2{};
int main(){
Derived derived;
//二义性问题解决
derived.func();
cout << derived.mParam << endl;
//输出结果:12
cout << "Derived size:" << sizeof(Derived) << endl;
return 0;
}
class BigBase{
public:
BigBase(int x){mParam = x;}
void func(){cout << "BigBase::func" << endl;}
public:
int mParam;
};
class Base1 : virtual public BigBase{
public:
Base1() :BigBase(10){} //不调用 BigBase 构造
};
class Base2 : virtual public BigBase{
public:
Base2() :BigBase(10){} //不调用 BigBase 构造
};
class Derived : public Base1, public Base2{
public:
Derived() :BigBase(10){} //调用 BigBase 构造
};
//每一次继承子类中都必须书写初始化语句
int main(){
Derived derived;
return 0;
}