目录
一、继承基本语法
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
//class News {
//public:
// void head()
// {
// cout << "公共头部" << endl;
// }
// void foot()
// {
// cout << "公共底部" << endl;
// }
// void left()
// {
// cout << "左侧列表" << endl;
// }
// void content()
// {
// cout << "新闻联播" << endl;
// }
//};
//
//class Sport {
//public:
// void head()
// {
// cout << "公共头部" << endl;
// }
// void foot()
// {
// cout << "公共底部" << endl;
// }
// void left()
// {
// cout << "左侧列表" << endl;
// }
// void content()
// {
// cout << "世界杯赛程" << endl;
// }
//
//};
//void test01()
//{
// cout << "新闻联播" << endl;
// News news;
// news.head();
// news.foot();
// news.left();
// news.content();
//
// cout << "体育播报" << endl;
// Sport sport;
// sport.head();
// sport.foot();
// sport.left();
// sport.content();
//}
//利用继承模拟网页
//继承优点:减少重复代码,提高代码的复用性
class BasePage {
public:
void head()
{
cout << "公共头部" << endl;
}
void foot()
{
cout << "公共底部" << endl;
}
void left()
{
cout << "左侧列表" << endl;
}
};
//语法
//class 子类 :继承方式 父类
//News 子类 派生类
//BasePage 父类 基类
class News : public BasePage {
public:
void content()
{
cout << "新闻联播" << endl;
}
};
class Sport : public BasePage {
public:
void content()
{
cout << "世界杯赛程" << endl;
}
};
void test01()
{
cout << "新闻联播界面" << endl;
News news;
news.head();
news.foot();
news.left();
news.content();
}
void test02()
{
cout << "体育赛事界面" << endl;
Sport sport;
sport.head();
sport.foot();
sport.left();
sport.content();
}
int main()
{
//test01();
test02();
system("pause");
return EXIT_SUCCESS;
}
二、继承方式
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Base {
public:
int m_A;
protected:
int m_B;
private:
int m_C;
};
/ 公共继承 /
class Son1 : public Base {
void fun1()
{
m_A = 100; //公共继承 公共属性 变成 公共属性
m_B = 100; //公共继承 保护属性 变成 保护属性
//m_C = 300; //私有属性 本身不可访问
}
};
void test()
{
Son1 son1;
son1.m_A = 200; //公共属性 类外 可以访问
//son1.m_B = 200; //保护属性 类外 不可访问
//son1.m_C = 200; //私有属性 类外 不可访问
}
class Son2 : protected Base {
void fun2()
{
m_A = 100; //保护继承 公共属性 变成 保护属性
m_B = 100; //保护继承 保护属性 变成 保护属性
//m_C = 100; //私有属性 本身不可访问
}
};
void test02()
{
Son2 son2;
//son2.m_A = 200; //保护属性 类外 不可访问
//son2.m_B = 200; //保护属性 类外 不可访问
//son2.m_C = 200; //私有属性 类外 不可访问
}
class Son3 : private Base {
void fun3()
{
//m_A = 100; //私有继承 公共属性 变成 私有属性
//m_B = 100; //私有继承 保护属性 变成 私有属性
//m_C = 100; //私有属性 本身不可访问
}
};
void test03()
{
Son3 son3;
//son2.m_A = 200; //私有属性 类外 不可访问
//son2.m_B = 200; //私有属性 类外 不可访问
//son2.m_C = 200; //私有属性 类外 不可访问
}
int main()
{
system("pause");
return EXIT_SUCCESS;
}
三、继承中对象模型
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Base {
public:
int m_A;
protected:
int m_B;
private:
int m_C; //父类中的私有属性 子类访问不到 是由编译器隐藏了
};
class Son : public Base {
public:
int m_D;
};
void test01()
{
cout << "sizeof(Son) = " << sizeof(Son) << endl; //16
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
如何查看这个类的模型呢?
先复制代码所在路径,打开开发人员命令提示
开始菜单->Visual Stdio 2022->
在路径中输入
cl /d1 reportSingleClassLayoutSon test.cpp
四、继承中的构造和析构顺序
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Base1 {
public:
Base1()
{
cout << "Base1构造函数调用" << endl;
}
~Base1()
{
cout << "Base1析构函数调用" << endl;
}
};
class Son1 : public Base1 {
public:
Son1()
{
cout << "Son1构造函数调用" << endl;
}
~Son1()
{
cout << "Son1析构函数调用" << endl;
}
};
void test01()
{
Son1 son;
}
class Base2 {
public:
Base2(int a)
{
m_A = a;
cout << "Base2构造函数调用" << endl;
}
int m_A;
};
class Son2 : public Base2 {
public:
Son2(int a) : Base2(a)
{
cout << "Son2构造函数调用" << endl;
}
};
void test02()
{
Son2 son2(1000);
cout << "m_A = " << son2.m_A << endl;
}
int main()
{
//test01();
test02();
system("pause");
return EXIT_SUCCESS;
}
test01输出结果:
test02输出结果
五、继承中同名成员处理
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Base {
public:
Base()
{
m_A = 10;
}
void func()
{
cout << "Base中func调用" << endl;
}
void func(int a)
{
cout << "Base中func(int)调用" << endl;
}
int m_A;
};
class Son : public Base {
public:
Son()
{
m_A = 20;
}
void func()
{
cout << "Son中func调用" << endl;
}
int m_A;
};
void test01()
{
Son s1;
cout << "s1.m_A = " << s1.m_A << endl;
//利用作用域访问父类成员
cout << "Base中的m_A = " << s1.Base::m_A << endl;
}
void test02()
{
Son s1;
s1.func();
s1.Base::func();
s1.Base::func(10);
//当子类重新定义父类中同名函数的时候 子类的成员函数会自动隐藏父类中所有重载函数版本 可利用作用域显示指定调用
}
int main()
{
//test01();
test02();
system("pause");
return EXIT_SUCCESS;
}
六、继承中同名静态成员处理
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Base {
public:
static void func()
{
cout << "Base中func()调用" << endl;
}
static void func(int a)
{
cout << "Base中func(int)调用" << endl;
}
static int m_A;
};
int Base::m_A = 10;
class Son : public Base {
public:
static void func()
{
cout << "Son中func()调用" << endl;
}
static int m_A;
};
int Son::m_A = 20;
void test01()
{
Son s1;
//1、通过对象
cout << "s1.m_A = " << s1.m_A << endl;
cout << "Base中的m_A = " << s1.Base::m_A << endl;
//2、通过类名
cout << "s1.m_A = " << Son::m_A << endl;
cout << "Base中的m_A = " << Son::Base::m_A << endl;
}
void test02()
{
Son s1;
//1、通过对象
s1.func();
s1.Base::func();
s1.Base::func(1);
//2、通过类名
Son::func();
Son::Base::func();
Son::Base::func(1);
}
int main()
{
//test01();
test02();
system("pause");
return EXIT_SUCCESS;
}
七、多继承语法
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Base1 {
public:
Base1()
{
m_A = 10;
}
int m_A;
};
class Base2 {
public:
Base2()
{
m_A = 20;
}
int m_A;
};
//多继承
class Son : public Base1, public Base2 {
public:
int m_B;
int m_C;
};
void test01()
{
Son s1;
cout << "sizeof(Son) = " << sizeof(Son) << endl;
//多继承中的同名函数问题 加作用域
cout << "Base1中的m_A = " << s1.Base1::m_A << endl;
cout << "Base2中的m_A = " << s1.Base2::m_A << endl;
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
八、菱形继承的问题及解决
使用虚继承
代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Animal {
public:
int m_A;
};
class Sheep : virtual public Animal {};
class Tuo : virtual public Animal{};
class SheepTuo : public Sheep, public Tuo {};
void test01()
{
SheepTuo st;
//st.m_A = 10; //m_A不明确
st.Sheep::m_A = 10;
st.Tuo::m_A = 20;
cout << "st.Sheep::m_A = " << st.Sheep::m_A << endl;
cout << "st.Tuo::m_A = " << st.Tuo::m_A << endl;
//当发生虚继承后 sheep和tuo类继承了一个vbptr指针 虚基类指针 指向一个虚基类表 vbtable
//虚基类表中记录了 偏移量 通过偏移量 可以找到唯一的一个m_A
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
不加virtual的输出结果:
加上virtual的输出结果: