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

发布时间:2024年01月07日

继承:

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

1.继承的基本语法:

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

例:

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.继承中的对象模型:

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

看下面代码:

//继承中的对象模型
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.继承中的构造和析构顺序:

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

//继承中的构造和析构顺序
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.继承同名成员处理方式:

访问子类同名成员,直接访问即可;
访问父类同名成员,需加作用域;

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
}

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

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.继承同名静态成员处理方式:

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)通过对象访问:

原理同上

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

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

Son : : Father :?: m_A;

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

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

7.多继承语法:

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

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

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.作用:使两个子类继承的实际为指针,创建孙子类时两个子类的指针都指向同一块数据。

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
}

文章来源:https://blog.csdn.net/2301_78922485/article/details/135431941
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。