2023年5月14日,博客摘录「 《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)」(关于派生)

1.在定义派生类对象时,构造函数的调用顺序如下:

 调用基类的构造函数,对基类数据成员初始化。

 调用子对象?的构造函数,对子对象的数据成员初始化。

         ?:对于复杂的成员函数来说。

 调用派生类的构造函数体,对派生类的数据成员初始化。

2.当基类构造函数不带参数时,派生类不一定需要定义构造函数;然而当基类的构造函数哪怕只带有一个参数,它所有的派生类都必须定义构造函数,甚至所定义的派生类构造函数的函数体可能为空,它仅仅起参数的传递作用,但是若基类使用默认构造函数或不带参数的构造函数,则在派生类中定义构造函数时可略去,但是每个派生类只对自己的基类负责,只需构造自己的基类中的数据成员。

3.派生类可以声明与基类成员同名的成员。在没有虚函数的情况下,如果在派生类中定义了与基类成员同名的成员,则称派生类成员覆盖了基类的同名成员,在派生类中使用这个名字意味着访问在派生类中声明的成员。为了在派生类中使用与基类同名的成员,必须在该成员名之前加上基类名和作用域标识符“::”。

3.1.访问声明的方法就是把基类的保护成员或共有成员直接写在私有派生类定义式中的同名段中,同时给成员名前冠以基类名和作用域标识符“::”。利用这种方法,该成员就成为派生类的保护成员或共有成员了。

class B : private A
{
public:
A::name;

}

4.虚基类的作用:如果一个类有多个直接基类,而这些直接基类又有一个共同的基类,则在最低层的派生类中会保留这个间接的共同基类数据成员的多份同名成员。在访问这些同名成员时,必须在派生类对象名后增加直接基类名,使其唯一地标识一个成员,以免产生二义性。 

class Base1:virtual public Base{
public:
	Base1() {
		a = a + 10;
		cout << "Base1 a = " << a << endl;
	}
};

class Base2:virtual public Base{
public:
	Base2() {
		a = a + 20;
		cout << "Base2 a = " << a << endl;
	}
};
————————————————
版权声明:本文为CSDN博主「白鳯」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44368437/article/details/117563488

4.1.建立一个对象时,如果这个对象中含有从虚基类继承来的成员,则虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。该派生类的其他基类对虚基类构造函数的调用都被自动忽略。若同一层次中同时包含虚基类和非虚基类,应先调用虚基类的构造函数,再调用非虚基类的构造函数,最后调用派生类构造函数。若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类的构造函数。

#include <iostream>
using namespace std;
class Base     //1
{
	int b;
public:
	Base(int x) : b(x) {}
	int getb()
	{
		return b;
	}
};
class Derived : public Base  //2
{
	int d;
public:
	Derived(int x, int y) :Base(x), d(y)
	{  }
	int getd()
	{
		return d;
	}
};

int  main()
{
	Base b1(11);
	Derived d1(22, 33);
	Derived d2(44, 55);
	cout << b1.getb() << endl;
	b1 = d1;								//第一种赋值兼容,直接赋值
	cout << "b1.getb( ) = " << b1.getb() << endl;
	//cout << "b1.getd( ) = " << b1.getd( ) << endl;无法访问



	Base* pb1 = &d2;						//第二种赋值兼容
	cout << "pb1->getb( ) = " << pb1->getb() << endl;
	//cout << "pb1->getd( ) = " << pb1->getd( ) << endl;无法访问	



	Derived* pd = &d1;
	Base* pb2 = pd;						//第三种赋值兼容!!!!!!!!!!!!!!!!
	cout << "pb2->getb( ) = " << pb2->getb() << endl;
	//cout << "pb2->getd( ) = " << pb2->getd( ) << endl;无法访问



	Base& rb = d1;							//第四种赋值兼容!!!!!!!!!!!!!!!!
	cout << "rb.getb( ) = " << rb.getb() << endl;
	//cout << "rb.getd( ) = " << rb.getd( ) << endl;无法访问
	delete pb2;
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值