c++学习第八讲---类和对象---继承

继承:

使子类(派生类)拥有与父类(基类)相同的成员,以节约代码量。

1.继承的基本语法:

class 子类名:继承方式 父类名{} ;

例:

cpp 复制代码
class father
{
public:
	int money;
	int debt;
};

class son :public father
{
private:
	int id;
};
int main()
{
	son s;
	s.debt = 20;//可以访问父类中的成员
}

从父类继承来的成员表现其共性,子类独有的成员表现其个性。

2.继承方式:

继承方式共有三种:

公共继承:public;保护继承:protected;私有继承:private。

总结:

1.父类中私有成员子类一定无法访问。

2.public > protected > private

父类中更公开的权限,如果比继承方式还要公开,则降为继承方式对应权限。

3.继承中的对象模型:

如果父类中的私有成员,子类访问不到,那这个成员是否属于子类呢?

看下面代码:

cpp 复制代码
//继承中的对象模型
class father
{
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};
class Son :public father
{
public:
	int m_D;
};
int main()
{
	cout << sizeof(Son) << endl;//结果为16
	return 0;
}

可以看到结果为16,说明父类中非静态的成员属性,都会被子类继承下去,只是父类中私有属性被隐藏了。

4.继承中的构造和析构顺序:

先构造父类,再构造子类;先析构子类,再析构父类

cpp 复制代码
//继承中的构造和析构顺序
class father
{
public:
	father()
	{
		cout << "father构造函数" << endl;
	}	
	~father()
	{
		cout << "father析构函数" << endl;
	}
};
class Son :public father
{
public:
	Son()
	{
		cout << "Son构造函数" << endl;
	}
	~Son()
	{
		cout << "Son析构函数" << endl;
	}
};
int main()
{
	Son s;
}

5.继承同名成员处理方式:

访问子类同名成员,直接访问即可;

访问父类同名成员,需加作用域;

cpp 复制代码
class father
{
public:
	father()
	{
		m_A = 100;
	}
	int m_A;
};
class Son :public father
{
public:
	Son()
	{
		m_A = 200;
	}
	int m_A;
};
int main()
{
	Son s;
	cout << s.m_A << endl;//200
	cout << s.father::m_A << endl;//访问父类,100
}

注:如果子类中出现了和父类同名成员函数,子类的桶面成员会隐藏掉父类中所有的同名成员函数,包括重载。

cpp 复制代码
class father
{
public:
	void func()
	{
		cout << "father::func调用" << endl;
	}
	void func(int a)
	{
		cout << "father::func(int a)调用" << endl;
	}
};
class Son :public father
{
public:
	void func()
	{
		cout << "son::func调用" << endl;
	}
};
int main()
{
	Son s;
	s.func();
	s.func(100);//报错,父类重载同名函数被隐藏,需加作用域
}

6.继承同名静态成员处理方式:

cpp 复制代码
class Father
{
public:
	static int m_A;
};
int Father::m_A = 100;
class Son :public Father
{
public:
	static int m_A;
};
int Son::m_A = 200;

(1)通过对象访问:

原理同上

cpp 复制代码
int main()
{
	Son s;
	cout << s.m_A << endl;//200
	cout << s.Father::m_A << endl;//100
	return 0;
}

(2)通过类名进行访问:

Son : : Father : : m_A;

//第一个 : : 代表通过类名的方式访问,第二个 : : 代表访问父类作用域下的成员

cpp 复制代码
int main()
{
	Son s;
	cout << Son::m_A << endl;//200
	//第一个::代表通过类名的方式访问,第二个::代表访问父类作用域下的成员
	cout << Son::Father::m_A << endl;//100
	return 0;
}

7.多继承语法:

class 子类 : 继承方式 父类1,继承方式 父类2 ......

(注:会有多个父类有同名成员的问题,不建议使用)

cpp 复制代码
class Father1
{
public:
	int A;
};
class Father2
{
public:
	int B;
};
class Son :public Father1, public Father2
{
	int C;
};
int main()
{
	cout << sizeof(Son) << endl;//3个int类型,结果为12
	return 0;
}

同名问题:需加作用域加以区分。

8.菱形继承:

两个子类继承同一个父类,又有一个类继承这两个子类,这种继承方式叫做菱形继承。

(1)菱形继承的问题:

1.两个子类都继承了父类的属性,当"孙子类"调用数据时,会产生二义性。

2.孙子类继承自两个子类的相同属性,只需一份即可。

(2)解决方法:虚继承

1.语法:在两个子类的继承方式前加上关键字 virtual ,父类称为虚基类。

2.作用:使两个子类继承的实际为指针,创建孙子类时两个子类的指针都指向同一块数据。

cpp 复制代码
class Father
{
public:
	int m_age;
};
class Son1 :virtual public Father{};
class Son2 :virtual public Father{};
class GrandSon :public Son1, public Son2{};
void test01()
{
	GrandSon p;
	p.Son1::m_age = 18;
	p.Son2::m_age = 20;
	cout << p.m_age << endl;//虚继承后,只有一份数据,结果为20
	cout << p.Son1::m_age << endl;//20
	cout << p.Son2::m_age << endl;//20
}
相关推荐
qianbo_insist13 分钟前
c++ python 共享内存
开发语言·c++·python
Coding小公仔41 分钟前
LeetCode 151. 反转字符串中的单词
开发语言·c++·算法
稳兽龙41 分钟前
P1098 [NOIP 2007 提高组] 字符串的展开
c++·算法·模拟
DKPT1 小时前
Java享元模式实现方式与应用场景分析
java·笔记·学习·设计模式·享元模式
算法练习生2 小时前
Qt核心类QWidget及其派生类详解
开发语言·c++·qt
Green1Leaves2 小时前
pytorch学习-11卷积神经网络(高级篇)
pytorch·学习·cnn
oioihoii2 小时前
C++11标准库算法:深入理解std::none_of
java·c++·算法
小汉堡编程5 小时前
数据结构——vector数组c++(超详细)
数据结构·c++
DKPT9 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式