子类继承父类问题?

xuxian02092213 2008-11-11 05:01:08
我有个问题,代码如下。
#include <stdio.h>
class Tank
{
public:
virtual void Shot();
virtual void Run();
};

class T50:public Tank
{
public:
T50()
{ }
public:
void Shot(){ printf("T50 is shoting\n");}
void Run() { printf("T50 is running\n");}
};

class Decorator: public Tank
{
public:
Tank *tank;
public:
Decorator(Tank *tank)
{
this->tank=tank;
}

virtual void Shot();
virtual void Run();
};

class DecoratorA:public Decorator
{
public:
DecoratorA(Tank *tank)
{
this->tank=tank;
}
void Shot()
{
//..功能的扩展
printf("The tank has DecoratorA Shot() function\n");
this->Shot();
}
void Run()
{ //..功能扩展
printf("The tank has DecoratorA Run() function\n");
this->Run();
}
};


void main()
{
Tank *tank = new T50();
DecoratorA *da= new DecoratorA(tank);
da->Shot();
getchar();
}


有个错误是:error C2512: “Decorator”: 没有合适的默认构造函数可用
...全文
208 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuedaoli 2008-11-12
  • 打赏
  • 举报
回复
把基类定义为虚基类
virtual void Shot() = 0;
muyingchi 2008-11-11
  • 打赏
  • 举报
回复
19楼,那个没问题吧,指针而已,他当然不可能传来一个Tank对象的指针了,这明显是多态啊。没问题的,而且也应该这样,不过如果使用这种封装,应该是
void Shot()
{
//..功能的扩展
printf("The tank has DecoratorA Shot() function\n");
tank->Shot();
}
void Run()
{ //..功能扩展
printf("The tank has DecoratorA Run() function\n");
tank->Run();
}

不知道楼主是不是想写成这样,不过如果使用这种设计模式,应该是这样的目的,派生于某一个类体系,但不改变类体系的情况下扩展功能,而原类体系相关的功能则通过一个原类体系的对象调用,tank就指向这个对象。
cottonmallow 2008-11-11
  • 打赏
  • 举报
回复
虚基类不能有自己的对象,所以
DecoratorA(Tank *tank)
{
this->tank=tank;
}

有问题!!自己在改改
hackers007 2008-11-11
  • 打赏
  • 举报
回复
#include <stdio.h>
class Tank
{
public:
virtual void Shot()=0;
virtual void Run()=0;
};

class T50:public Tank
{
public:
T50()
{ }
public:
void Shot(){ printf("T50 is shoting\n");}
void Run() { printf("T50 is running\n");}
};

class Decorator: public Tank
{
public:
Tank *tank;
public:
Decorator(Tank *tank)
{
this->tank=tank;
}

virtual void Shot(){printf("Decorator void Shot()");}
virtual void Run(){printf("Decorator void Run()");}
};

class DecoratorA:public Decorator
{
public:
DecoratorA(Tank *tank)
:Decorator(tank)
{
}
void Shot()
{
//..功能的扩展
printf("The tank has DecoratorA Shot() function\n");
}
void Run()
{ //..功能扩展
printf("The tank has DecoratorA Run() function\n");
}
};


void main()
{
Tank *tank = new T50();
DecoratorA *da= new DecoratorA(tank);
da->Shot();
getchar();
}
muyingchi 2008-11-11
  • 打赏
  • 举报
回复
如果不写实现,Tank子类对象在创建时会创建一份Tank副本在子类对象中,连函数都没有实现,这份副本就完全不能用了,虚函数表也不能创建了。一点你写了Tank::Shot(),他更不知道去调什么了。但是如果他不是最上层的父类,这没有问题,因为继承了父类的函数,使用父类的函数实现,而且虚函数表也存放父类函数指针,这样就没问题了。
muyingchi 2008-11-11
  • 打赏
  • 举报
回复
如果你不用那个类,当然不需要写实现,不巧现在用到了,当然要写了
luojc714 2008-11-11
  • 打赏
  • 举报
回复
路过
xuxian02092213 2008-11-11
  • 打赏
  • 举报
回复
我记得以前我写虚函数的时候,是不需要给出定义的啊。难道真的是我记错了!
muyingchi 2008-11-11
  • 打赏
  • 举报
回复
当然了,链接错误不是这个原因,是没写Tank类的两个函数实现
muyingchi 2008-11-11
  • 打赏
  • 举报
回复

void Shot()
{
//..功能的扩展
printf("The tank has DecoratorA Shot() function\n");
Decorator::Shot();
}
void Run()
{ //..功能扩展
printf("The tank has DecoratorA Run() function\n");
Decorator::Run();
}


这样用
muyingchi 2008-11-11
  • 打赏
  • 举报
回复
不是这样用的,要不就显示调用父类的虚函数,并在子类中调用写入扩展代码,要不就以聚合方式,包含父类的一个对象来扩展。直接this->会调用子类自己的虚函数,而不是父类的功能。
xuxian02092213 2008-11-11
  • 打赏
  • 举报
回复
我想调用T50里面的shot()
函数,以实现扩展同版本号相分离。这是设计模式中的Decorator模式啊
grellen 2008-11-11
  • 打赏
  • 举报
回复
函数没有定义
fox000002 2008-11-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 xuxian02092213 的回复:]
上面的依然有问题啊。错误代码是:

错误 1 error LNK2001: 无法解析的外部符号 "public: virtual void __thiscall Tank::Shot(void)" (?Shot@Tank@@UAEXXZ) Decorator.obj
错误 2 error LNK2001: 无法解析的外部符号 "public: virtual void __thiscall Tank::Run(void)" (?Run@Tank@@UAEXXZ) Decorator.obj
错误 3 error LNK2001: 无法解析的外部符号 "public: virtual void __thiscall Decorator::Shot(void)" (?Shot@Deco…
[/Quote]

lz 没写实现代码啊,至少加个空的 {} 啊
muyingchi 2008-11-11
  • 打赏
  • 举报
回复
elephont9527 说的不会导致编译错误,但是,你父类如果不写实现就写成纯虚的,不要写了,还不写实现,链接当然不过
muyingchi 2008-11-11
  • 打赏
  • 举报
回复
大哥,函数没写实现啊
elephont9527 2008-11-11
  • 打赏
  • 举报
回复
void Shot()
{
//..功能的扩展
printf("The tank has DecoratorA Shot() function\n");
this->Shot();
}
void Run()
{ //..功能扩展
printf("The tank has DecoratorA Run() function\n");
this->Run();
}
晕死,Shot()里边调用this->Shot(),干嘛呢这是
xuxian02092213 2008-11-11
  • 打赏
  • 举报
回复
上面的依然有问题啊。错误代码是:

错误 1 error LNK2001: 无法解析的外部符号 "public: virtual void __thiscall Tank::Shot(void)" (?Shot@Tank@@UAEXXZ) Decorator.obj
错误 2 error LNK2001: 无法解析的外部符号 "public: virtual void __thiscall Tank::Run(void)" (?Run@Tank@@UAEXXZ) Decorator.obj
错误 3 error LNK2001: 无法解析的外部符号 "public: virtual void __thiscall Decorator::Shot(void)" (?Shot@Decorator@@UAEXXZ) Decorator.obj
错误 4 error LNK2001: 无法解析的外部符号 "public: virtual void __thiscall Decorator::Run(void)" (?Run@Decorator@@UAEXXZ) Decorator.obj
Lnnu_lc 2008-11-11
  • 打赏
  • 举报
回复
楼上两个都说的很对啊,那些都是编译器有时候做了一些事情,你不知道,但是没影响你,所以你没注意,其实这些都应该是你要注意到的问题
liumingrong 2008-11-11
  • 打赏
  • 举报
回复
继承类对象构造时会依次调用基类构造函数,缺省时是默认的无参构造函数(你没有写任何构造函数时编译器会帮你生成一个默认的)
但是Decorator类中你写了一个
Decorator(Tank *tank)
{
this->tank=tank;
}
编译器不再构造默认的,调用会失败
可以采用elephont9527的方法显示调用基类构造函数
加载更多回复(1)

64,653

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧