C++名字冲突问题和钻石继承


C++名字冲突问题:

什么是C++的名字冲突,假如一个子类继承基类,基类中有相同的成员变量和成员函数名,这样在子类对象调用中就存在歧义,这就是名字冲突,解决办法就是使用作用域限定符指明基类中成员属于谁,具体代码如下:

#include <iostream>
using namespace std;
class A {
public:
	int m_data;
	void foo(void){
		cout<<m_data<<endl;
	}
};
class B{
public:
	float m_data;
	void foo(int var){
		cout<<m_data<<endl;
	}

};
class C:public A,public B{
	
	
};
int main(void){
	C c;
	c.A::m_data =10;//指明是谁的成员
	c.B::m_data =1.2;
	c.A::foo(); //指明是谁的函数
	c.B::foo(1);
	return 0;
}

 

虚拟继承解决钻石继承的不足:

所谓的钻石继承,就是基类中的继承就沿着多条不同的路,基类中的数据就会有多份不同的拷贝。你从多处访问时就会有不一致现象,会出现问题。

#include <iostream>
using namespace std;
class A{
public:
	A(int data):m_data(data){}
	int m_data;
};
class B:public A{
public:
	B(int data):A(data){}
	void set(int data){
		m_data= data;
	}
};
class C:public A{
public:
	C(int data):A(data){}
	int get(void){
		return m_data;
	}
}
class D:public B,public C{
public:
	D(int data):B(data),C(data){}
};
int main(void){
	D d(1000);
	d.set(2000);
	cout<<d.get()<<endl;//?1000
	return 0;
}


为什么打印出来的值是1000呢?

首先A B C D的继承关系如图,A在B,C中都有一份,m_data初始值都为1000;但是调用set的时候只是将B中的m_data变为2000;C中的m_data还是为1000,然后调用C中的get得到的值当然就是1000了;

其实理想的状态应该是这样的:A的数据在B和C中共享,有点类似共享内存呢?

那么我们怎么做到呢,现在就要用到虚继承,将上面代码修改如下:

#include <iostream>
using namespace std;
class A{
public:
	A(int data):m_data(data){}
	int m_data;
};
class B:virtual public A{ //增加virtual
public:
	B(int data):A(data){}
	void set(int data){
		m_data= data;
	}
};
class C:virtual public A{ //增加virtual
public:
	C(int data):A(data){}
	int get(void){
		return m_data;
	}
}
class D:public B,public C{
public:
	D(int data):B(data),C(data),A(data){} //对A进行构造
};
int main(void){
	D d(1000);
	d.set(2000);
	cout<<d.get()<<endl;//?2000
	return 0;
}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值