C++基础(七)——多重继承

01 虚基类和虚继承

多重继承 :代码的复用 一个派生类有多个基类

class C: public A, public B

{

};

抽象类(有纯虚函数的类) / 虚基类 被虚继承的类称作虚基类 vbptr和vbtable

virtual

1.修饰成员方法是虚函数

2.可以修饰继承方式,是虚继承。被虚继承的类,称作虚基类

class A
{
public:
	virtual void func() { cout << "call A::func" << endl; }
	void operator delete(void *ptr)
	{
		cout << "operator delete p:" << ptr << endl;
		free(ptr);
	}
private:
	int ma;
};
class B : virtual public A
{
public:
	void func() { cout << "call B::func" << endl; }

	void* operator new(size_t size)
	{
		void *p = malloc(size);
		cout << "operator new p:" << p << endl;
		return p;
	}
private:
	int mb;
};
/*
A a; 4个字节
B b; ma,mb  8个字节+4=12个字节   vbptr
*/
int main()
{
	// 基类指针指向派生类对象,永远指向的是派生类基类部分数据的起始地址
	B b;
	A *p = &b;//new B(); // B::vftable
	cout << "main p:" << p << endl;
	p->func();
	//delete p;

	return 0;
}

02 菱形继承

C++的多重继承 - 菱形继承的问题 派生类有多份间接基类的数据 设计的问题

好处,可以做更多代码的复用 D -> B,C B *p = new D() C *p = new D()

class A
{
public:
	A(int data) :ma(data) { cout << "A()" << endl; }
	~A() { cout << "~A()" << endl; }
protected:
	int ma;
};
//=======================================
class B : virtual public A
{
public:
	B(int data) :A(data), mb(data) { cout << "B()" << endl; }
	~B() { cout << "~B()" << endl; }
protected:
	int mb;
};
class C : virtual public A
{
public:
	C(int data) :A(data), mc(data) { cout << "C()" << endl; }
	~C() { cout << "~C()" << endl; }
protected:
	int mc;
};
//=========================================
class D : public B, public C
{
public:
	//“A::A”: 没有合适的默认构造函数可用
	D(int data) :A(data), B(data), C(data), md(data) { cout << "D()" << endl; }
	~D() { cout << "~D()" << endl; }
protected:
	int md;
};
int main()
{
	D d(10);

	return 0;
}

03 C++四种类型转换

C++语言级别提供的四种类型转换方式

int a = (int)b;

const_cast : 去掉(指针或者引用)常量属性的一个类型转换

static_cast : 提供编译器认为安全的类型转换(没有任何联系的类型之间的转换就被否定了)

reinterpret_cast : 类似于C风格的强制类型转换

dynamic_cast : 主要用在继承结构中,可以支持RTTI类型识别的上下转换

class Base
{
public:
	virtual void func() = 0;
};
class Derive1 : public Base
{
public:
	void func() { cout << "call Derive1::func" << endl; }
};
class Derive2 : public Base
{
public:
	void func() { cout << "call Derive2::func" << endl; }
	// Derive2实现新功能的API接口函数
	void derive02func() 
	{ 
		cout << "call Derive2::derive02func" << endl; 
	}
};
/*
typeid(*p).name() == "Derive"
*/
void showFunc(Base *p)
{
	// dynamic_cast会检查p指针是否指向的是一个Derive2类型的对象?
	// p->vfptr->vftable RTTI信息 如果是,dynamic_cast转换类型成功,
	// 返回Derive2对象的地址,给pd2;否则返回nullptr
	// static_cast编译时期的类型转换  dynamic_cast运行时期的类型转换 支持RTTI信息识别
	Derive2 *pd2 = dynamic_cast<Derive2*>(p);
	if (pd2 != nullptr)
	{
		pd2->derive02func();
	}
	else
	{
		p->func(); // 动态绑定  *p的类型 Derive2  derive02func
	}
}
int main()
{
	Derive1 d1;
	Derive2 d2;
	showFunc(&d1);
	showFunc(&d2);

	//static_cast 基类类型 《=》 派生类类型  能不能用static_cast?当然可以!
	//int *p = nullptr;
	//double* b = reinterpret_cast<double*>(p);

	//const int a = 10;
	//int *p1 = (int*)&a;
	//int *p2 = const_cast<int*>(&a);
	// const_cast<这里面必须是指针或者引用类型 int* int&>
	//int b = const_cast<int>(a);

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-特立独行的猪-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值