C++继承

通过这个例子发现对面向对象的继承还是没有理解到位,还需努力。

#include<iostream>
#include<string>
using namespace std;
const int ESPRESSO_PRICE=25;
const int DARKROAST_PRICE=20;
const int MOCHA_PRICE=10;
const int WHIP_PRICE=8;
class Beverage{
protected:
	string description;
public:
	virtual string getDescription(){return description;}
	virtual int cost()=0;
};
class CondimentDecorator:public Beverage{//配料 
	protected:
	Beverage* beverage;
	public:	
};
class Espresso:public Beverage{	//蒸馏咖啡 
	public:
	Espresso(){description="Espresson";}
	int cost(){return ESPRESSO_PRICE;}
};
class DarkRoast:public Beverage{//深度烘焙咖啡 
	public:
	DarkRoast(){cout<<"DarkRoast的构造函数\n";description="DarkRoast";}
	int cost(){cout<<"DarkRoast的cost\n";return DARKROAST_PRICE;}
};
class Mocha:public CondimentDecorator{//摩卡 
	public:
	Mocha(){}
	Mocha(Beverage* beverage){this->beverage=beverage;}
	string getDescription(){cout<<"Mocha的getdec\n";return beverage->getDescription()+",Mocha";}
	int cost(){cout<<"Mocha的cost\n";return MOCHA_PRICE+beverage->cost();}
};
class Whip:public CondimentDecorator{//奶泡 
	public:
	Whip(){}
	Whip(Beverage* beverage){this->beverage=beverage;}
	string getDescription(){cout<<"Whip的getdec\n";return beverage->getDescription()+",Whip";}
	int cost(){cout<<"Whip的cost\n";return WHIP_PRICE+beverage->cost();}
};
int main()
{
	Beverage* bg=new DarkRoast();
	bg=new Mocha(bg);
	bg=new Whip(bg);
	cout<<bg->getDescription()<<"¥"<<bg->cost()<<endl;
	return 0;
}

刚开始看到这个程序的时候,不太理解为什么输出是DarkRoast,Mocha,Whip¥38。

感觉Mocha和Whip两个子类里的this->beverage改变的明明都是DarkRoast的beverage,结果却能起到Whip-Mocha-DarkRoast层层向上的作用。

后来经过测试才发现,Mocha和Whip继承了DarkRoast之后,每个子类会单独拥有一个beverage属性。

当父类指针指向子类的对象时,这个子类的beverage才是和DarkRoast的beverage关联的,因为主函数里自始至终只用了一个Beverage*的指针


这里先把总结写下来,再做下面的讨论:

在只用一个父类指针指向不同对象的情况下。

(1)对于从父类继承而来,子类中没有另外声明的属性x,子类对象之间没有影响(可以赋不同值)。

(2)同一时间,只有一个子类对象的属性x的改变会影响父类对象的属性(因为只有一个父类指针)


接下里逐步考虑主函数里的语句做了什么:

(0)首先明确一点是,只有CondimentDecorator里声明了Beverage* beverage,其余类只是使用。

(1)执行Beverage* bg=new DarkRoast();时,bg指向DarkkRoast的对象。

(2)执行bg=new Mocha(bg)时,根据Mocha类的自定义构造函数,把Mocha对象中的beverage指向DarkRoast(此时在Mocha类中beverage->getDescription()就会去执行DarkRoast的getDescription方法),此时父类CondimentDecorator对象里的beverage也同样指向了DarkRoast,此时这两个是关联的。这条语句执行完之后,bg就指向了Mocha。

(3)执行bg=new Whip(bg)时,把Whip对象中的beverage指向了Mocha,但要注意的是,此时Mocha对象中的beverage没有改变!!只是CondimentDecorator对象“跟随”Whip对象里的beverage一起指向了Mocha。执行完之后,bg指向Whip

(4)bg->getDescription()时,因为bg指向Whip,先执行Whip的getDescription(),由于该方法返回的是beverage->getDescription()+",Whip",而此时Whip对象的beverage指向的是Mocha,所以就又会去调用Mocha的getDescription()方法,如此就得到了上面的输出。


下面附上一个可以检验结果的例子

#include<iostream>
#include <typeinfo>
#include<string>
using namespace std;
const int ESPRESSO_PRICE=25;
const int DARKROAST_PRICE=20;
const int MOCHA_PRICE=10;
const int WHIP_PRICE=8;
class A{
	protected:
	int num;
	public:
	virtual void setV(int b){
		num=b;
	}
	virtual void pt(){
		cout<<"我是A:"<<num<<endl;
	}
	void testA(){
		cout<<"我是A的test:"<<num<<endl;
	}
	void setA(int v){
		num=v;
	}
};
class B:public A{
	public:
	void setV(int c){
		this->num=c*2;
	}
	void pt(){
		cout<<"我是B:"<<num<<endl;
	}
	void testB(){
		cout<<"我是B的test:"<<num<<endl;
	}
};
class C:public A{
	public:
	void setV(int d){
		this->num=d*3;
	}
	void pt(){
		cout<<"我是C:"<<num<<endl;
	}
	void testC(){
		cout<<"我是C的test:"<<num<<endl;
	}
};
int main()
{
	A* a=new A();
	B* b=new B();
	C* c=new C();
	
	//把a指向b,赋值后只有a,b有值且相等,c仍然是脏数据 
	a=b;
	a->setV(5);
	cout<<"a指向b"<<endl;
	a->testA();
	b->testB();
	c->testC();
	cout<<"\n\n";
	
	//把a指向c,赋值后,a值随着c而改变,b值不变 
	a=c;
	a->setV(5);
	cout<<"a指向c"<<endl;
	a->testA();
	b->testB();
	c->testC();
	cout<<"\n\n";
	
	//调用a的方法对a赋值,赋值后,c值随着a而改变,b值不变 
	a->setA(2);
	a->testA();
	b->testB();
	c->testC();
	cout<<"\n\n";
	
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值