首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

大概关于虚函数的有关问题

2012-03-21 
大概关于虚函数的问题 在第33行,ptr-cloen(),clone()是虚函数,所以会调用第21行Dog类哪的clone()函数。我

大概关于虚函数的问题

在第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         }



[解决办法]
派生类的指针可以直接赋给基类的指针,反之则有强制类型转换
[解决办法]
ptr是一个 Mammal 类指针,就如同ls说的“派生类的指针可以直接赋给基类的指针”,这一Mammal 类指针指向一个dog类对象,所白了就是一个dog实例的首地址。
在第21行里, clone()函数内的代码 this 应该是一个 Dog 类的指针-----》由于clone是虚函数,虽然ptr是指向dog类对象的mamal指针,调用时,要用dog类中的clone函数,而你认为此时this指向一个mamal对象了,其实不是,指向的是dog对象
这个就是虚函数的多态性的一个例子
[解决办法]
而ptr是一个 Mammal 类指针, 为什么不会产生错误呢

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

而反过来是可能会发生错误的,
所以不允许 用派生类类型指针 赋值为 基类类型指针。
[解决办法]
基类类型 *pBase = new 派生类类型; //OK
派生类类型 *pDrived = new 基类类型; //Error !

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

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

如果还不理解,
记住这个规则,以后再慢慢理解去吧。
[解决办法]
建议楼主看看C++的虚函数机制

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



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

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

Mammal* CreateMamal(Mammal* pM)
{
return pM-> clone(); //调用clone()方法实现克隆
}
在这个函数里,我们不知道任何pM所指向的实际的类信息,但是通过虚机制,我们却能准确地复制一份pM所指向类的拷贝

热点排行