构造函数不能是虚函数。但有时候确实需要能传递一个指向基类对象的指针,并且有已创建的派生类对象的拷贝。通常在类内部创建一个Clone()方法,并设置为虚函数。

//Listing 12.11 Virtual copy constructor
#include <iostream>
using namespace std;class Mammal
{public:Mammal():itsAge(1) { cout << "Mammal constructor...\n"; }virtual ~Mammal() { cout << "Mammal destructor...\n"; }Mammal (const Mammal & rhs);virtual void Speak() const { cout << "Mammal speak!\n"; }virtual Mammal* Clone() { return new Mammal(*this); }int GetAge()const { return itsAge; }protected:int itsAge;
};Mammal::Mammal (const Mammal & rhs):itsAge(rhs.GetAge())
{cout << "Mammal Copy Constructor...\n";
}class Dog : public Mammal
{public:Dog() { cout << "Dog constructor...\n"; }virtual ~Dog() { cout << "Dog destructor...\n"; }Dog (const Dog & rhs);void Speak()const { cout << "Woof!\n"; }virtual Mammal* Clone() { return new Dog(*this); } // 这里!
};Dog::Dog(const Dog & rhs):
Mammal(rhs)
{cout << "Dog copy constructor...\n";
}class Cat : public Mammal
{public:Cat() { cout << "Cat constructor...\n"; }~Cat() { cout << "Cat destructor...\n"; }Cat (const Cat &);void Speak()const { cout << "Meow!\n"; }virtual Mammal* Clone() { return new Cat(*this); }
};Cat::Cat(const Cat & rhs):
Mammal(rhs)
{cout << "Cat copy constructor...\n";
}enum ANIMALS { MAMMAL, DOG, CAT};
const int NumAnimalTypes = 3;
int main()
{Mammal *theArray[NumAnimalTypes];Mammal* ptr;int choice, i;for ( i = 0; i<NumAnimalTypes; i++){cout << "(1)dog (2)cat (3)Mammal: ";cin >> choice;switch (choice){case DOG:   ptr = new Dog;break;case CAT:   ptr = new Cat;break;default:   ptr = new Mammal;break;}theArray[i] = ptr;}Mammal *OtherArray[NumAnimalTypes];for (i=0;i<NumAnimalTypes;i++){theArray[i]->Speak();OtherArray[i] = theArray[i]->Clone();}for (i=0;i<NumAnimalTypes;i++)OtherArray[i]->Speak();return 0;
}

输出结果:

(1)dog (2)cat (3)Mammal: 3
Mammal constructor...
Woof!
Mammal Copy Constructor...
Dog copy constructor...

Meow!
Mammal Copy Constructor...
Cat copy constructor...
Mammal speak!
Mammal Copy Constructor...
Woof!
Meow!
Mammal speak!

C++虚复制构造函数,设置Clone()方法返回基类指针,并设置为虚函数相关推荐

  1. 【C++】继承和派生、虚继承和虚基类、虚基类表和虚基类指针

    继承和派生.虚继承和虚基类.虚基类表和虚基类指针 继承和派生 继承概述 继承基本概念 派生类中的成员 继承的内容 派生类定义 派生类访问控制 对象构造和析构 对象构造和析构的调用顺序 继承中的构造和析 ...

  2. 虚析构函数? vptr? 指针偏移?多态数组? delete 基类指针 内存泄漏?崩溃?...

    五条基本规则: 1.如果基类已经插入了vptr, 则派生类将继承和重用该vptr.vptr(一般在对象内存模型的顶部)必须随着对象类型的变化而不断地改变它的指向,以保证其值和当前对象的实际类型是一致的 ...

  3. C++中虚继承产生的虚基类指针和虚基类表,虚函数产生的虚函数指针和虚函数表

    本博客主要通过查看类的内容的变化,深入探讨有关虚指针和虚表的问题. 一.虚继承产生的虚基类表指针和虚基类表 如下代码:写一个棱形继承,父类Base,子类Son1和Son2虚继承Base,又来一个类Gr ...

  4. C++ day22 继承(二)基类指针数组通过虚方法实现智能的多态

    继承一共有三种: 公有继承 私有继承 保护继承 文章目录 公有继承 基类和派生类的关系 is-a(用公有继承表示"是一种"的关系) has-a uses-a is-like-a i ...

  5. C++多继承中重写不同基类中相同原型的虚函数

    在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA  {  public:  virtual void TestA();  };  class ...

  6. 指向派生类对象的基类指针与虚函数

    看如下代码: CSales   aSales("崔贤"); CSales* pSales; CWage* pWager; pSales=&aSales; pWager=&a ...

  7. C++通过基类指针delete派生类数组,析构函数是虚函数,程序为什么会崩溃? https://www.zhihu.com/question/30838092/answer/49623765

    https://www.zhihu.com/question/30838092/answer/49623765 C++通过基类指针delete派生类数组,析构函数是虚函数,程序为什么会崩溃? 代码如下 ...

  8. Cpp 对象模型探索 / 多重继承下基类指针释放子类对象的原理说明(虚析构函数的作用)

    源码 #include <iostream>class Base1 { public:virtual void func_1_1(){ std::cout << "B ...

  9. JS-对象/Date 日期对象/返回/设置年份方法/返回星期方法/返回(/设置)时间方法

    什么是对象 JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法. 对象的属性:反映该对象某些特定的性质的,如:字符串的长度.图像的长宽等: 对象的方法: ...

  10. java方法返回值_如何高效率的学习Java函数返回值

    一.概述 函数返回处理值有两种方式,一种直接利用函数返回值返回:另一种通过输出参数返回,一般传入的值为引用或者指针. public Foo Function1(); // 函数返回值的形式 publi ...

最新文章

  1. spark Tachyon
  2. mysql 分页查询时,如何正确的获取总数
  3. 怎么把一台华为路由器配置为FTP服务器?
  4. android image 位移动画_深入理解Android之动画
  5. [FW]软件开发中的11个系统思维定律
  6. unc 隐藏共享文件夹_你真的了解任务栏吗?win10任务栏居然隐藏了这么多小窍门...
  7. VSCode 如何支持 Flow
  8. 条件变量的陷阱,惊群效应(转载)
  9. 服务器怎么修改远程桌面端口号,windows系统如何修改默认的远程桌面端口 如何更改服务器远程端口...
  10. 关于原生HTML+CSS div的高度随着宽度按比例缩放
  11. 通过SCDM导入CAD几何模型到Icepak_51CAE_新浪博客
  12. 2013/06 事情发生之后都会显得云淡风轻
  13. (Java-11)简单的银行账户模拟
  14. HTTP POST 参数格式
  15. pulsar BookieException$InvalidCookieException 异常
  16. tableView表格重写表头增加全选功能和实现翻页(读写excel和读ini)
  17. 【易购管理系统】导航折叠效果
  18. linux c 语言uint32 t,Linux中uint16_t
  19. 线性表-顺序表的基本操作
  20. 台大郭彦甫_MATLAB视频笔记(六)图形界面_GUI程序设计

热门文章

  1. 很犀利却很现实的26句话!哪句你心痛了
  2. 获取桌面DC: GetDC(GetDesktopWindow())与GetDC(NULL)
  3. 查找数组中特定元素_Leetcode 540 题 有序数组中的单一元素
  4. 通过 Socket 实现 UDP 编程 入门
  5. 基于c语言的成绩管理系统,基于C语言实现学生成绩管理系统.docx
  6. 大数据算法_大数据算法下的我们,犹如“皇帝的新衣”
  7. 英语字帖电子版可打印_一年级英语字母专项练习:含26个英文字母书写教学 可下载电子版...
  8. python程序设计第二版课后答案江红_Python核心编程第二版 第十三章课后答案
  9. python做数据可视化的优势_用Python进行数据可视化的10种方法
  10. 如你以安全模式启动计算机,如何以安全模式启动计算机?