大概关于虚函数的问题

akey307 2007-08-07 03:30:09

在第33行, ptr -> cloen(), clone()是虚函数, 所以会调用第21行Dog类哪的clone()函数。

我的问题是: 在第21行里, clone()函数内的代码 this 应该是一个 Dog 类的指针, 而ptr是一个 Mammal 类指针, 为什么不会产生错误呢?

谢谢


1 #include <iostream>
2
3 using namespace std;
4
5 class Mammal
6 {
7 public:
8 Mammal(){};
9 virtual ~Mammal() {};
10 Mammal(const Mammal&) {};
11 virtual Mammal* clone() {return new Mammal(*this);}
12 };
13
14
15 class Dog : public Mammal
16 {
17 public:
18 Dog() {};
19 virtual ~Dog() {};
20 Dog(const Dog&);
21 virtual Mammal* clone() {return new Dog(*this);}
22 };
23
24
25 Dog::Dog(const Dog& rhs):
26 Mammal(rhs)
27 {}
28
29
30 int main(void)
31 {
32 Mammal *ptr = new Dog;
33 Mammal *p = ptr -> clone();
34 return 0;
35 }

...全文
195 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
jxlczjp77 2007-08-07
  • 打赏
  • 举报
回复
建议楼主看看C++的虚函数机制

这个clone()方法是设计模式里的 原型模式,能在不知道具体子类的情况下实现对子类的克隆。

通过基类的指针调用虚函数clone(),而虚函数机制会关联到实际子类clone()函数,再由实际的子类完成自我复制。

比如有这样一个函数:Mammal* CreateMamal(Mammal* pM)能根据传进来的pM指针复制生成一个类Mammal

Mammal* CreateMamal(Mammal* pM)
{
return pM->clone(); //调用clone()方法实现克隆
}
在这个函数里,我们不知道任何pM所指向的实际的类信息,但是通过虚机制,我们却能准确地复制一份pM所指向类的拷贝
lockhall 2007-08-07
  • 打赏
  • 举报
回复
派生类的指针可以直接赋给基类的指针,反之则有强制类型转换

這句說的好。:)
jixingzhong 2007-08-07
  • 打赏
  • 举报
回复
基类类型 *pBase = new 派生类类型; //OK
派生类类型 *pDrived = new 基类类型; //Error !

由于派生,
pDrived 允许的调用,比如某个方法,
可能是 基类 中不支持的,
那么 pDrived->该方法 就会发生错误。

而pBase 允许的调用,
new 派生类类型 返回的对象实例必然是可用的。

如果还不理解,
记住这个规则,以后再慢慢理解去吧。
jixingzhong 2007-08-07
  • 打赏
  • 举报
回复
而ptr是一个 Mammal 类指针, 为什么不会产生错误呢

派生类类型指针 赋值给 基类类型指针是可以的,
因为 基类指针 所允许的调用,派生类类型指针都可以完成。

而反过来是可能会发生错误的,
所以不允许 用派生类类型指针 赋值为 基类类型指针。
dabang_007 2007-08-07
  • 打赏
  • 举报
回复
ptr是一个 Mammal 类指针,就如同ls说的“派生类的指针可以直接赋给基类的指针”,这一Mammal 类指针指向一个dog类对象,所白了就是一个dog实例的首地址。
在第21行里, clone()函数内的代码 this 应该是一个 Dog 类的指针-----》由于clone是虚函数,虽然ptr是指向dog类对象的mamal指针,调用时,要用dog类中的clone函数,而你认为此时this指向一个mamal对象了,其实不是,指向的是dog对象
这个就是虚函数的多态性的一个例子
gfxiang 2007-08-07
  • 打赏
  • 举报
回复
派生类的指针可以直接赋给基类的指针,反之则有强制类型转换

64,680

社区成员

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

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