C++虚复制构造函数,设置Clone()方法返回基类指针,并设置为虚函数
构造函数不能是虚函数。但有时候确实需要能传递一个指向基类对象的指针,并且有已创建的派生类对象的拷贝。通常在类内部创建一个Clone()方法,并设置为虚函数。
//Listing 12.11 Virtual copy constructor
#include <iostream>
using namespace std; class Mammal
{
public:
Mammal():itsAge() { 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 = ;
int main()
{
Mammal *theArray[NumAnimalTypes];
Mammal* ptr;
int choice, i;
for ( i = ; 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=;i<NumAnimalTypes;i++)
{
theArray[i]->Speak();
OtherArray[i] = theArray[i]->Clone();
}
for (i=;i<NumAnimalTypes;i++)
OtherArray[i]->Speak();
return ;
}
输出结果:
(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()方法返回基类指针,并设置为虚函数的更多相关文章
- 虚析构函数? vptr? 指针偏移?多态数组? delete 基类指针 内存泄漏?崩溃?
五条基本规则: 1.如果基类已经插入了vptr, 则派生类将继承和重用该vptr.vptr(一般在对象内存模型的顶部)必须随着对象类型的变化而不断地改变它的指向,以保证其值和当前对象的实际类型是一致的 ...
- 【转载】 C++多继承中重写不同基类中相同原型的虚函数
本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: ...
- 读书笔记 effective c++ Item 7 在多态基类中将析构函数声明为虚析构函数
1. 继承体系中关于对象释放遇到的问题描述 1.1 手动释放 关于时间记录有很多种方法,因此为不同的计时方法创建一个TimeKeeper基类和一些派生类就再合理不过了: class TimeKeepe ...
- C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构
一.基类指针.派生类指针 父类指针可以new一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型 ...
- C++基类的析构函数定义为虚函数的原因
1:每个析构函数只会清理自己的成员(成员函数前没有virtual).2:可能是基类的指针指向派生类的对象,当析构一个指向派生类的成员的基类指针,这时程序不知道这么办,可能会造成内存的泄露,因此此时基类 ...
- C++的派生类构造函数是否要带上基类构造函数
//public:Student(int s_age):People(s_age) //C++的派生类构造函数后面是否带上基类构造函数,取决于基类构造函数是否需要传入参数,如果要参数,就一定带上:不需 ...
- 不要在基类析构函数中调用纯虚函数,否则运行时会报错“pure virtual method called”
如上. 这是因为:delete派生类对象时,先调用派生类的析构函数,然后再调用基类的析构函数:此时如果调用纯虚函数的话,派生类的对象已经被破坏了,所以会报错. http://www.cnblogs.c ...
- Field的getModifiers()方法返回int类型值表示该字段的修饰符
其中,该修饰符是java.lang.reflect.Modifier的静态属性. 对应表如下: PUBLIC: 1PRIVATE: 2PROTECTED: 4STATIC: 8FINAL: 16SYN ...
- Effective Java 第三版——13. 谨慎地重写 clone 方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
随机推荐
- TMOS_Order_of_Operations_v0.1
- 【Luogu】P3847调整队形(DP)
题目链接 DP果真是考思维啊 增加一个数的操作等价于删掉那个不和谐的数的操作. 所以1.2操作可以忽略. 剩下3.4操作,则可以设计f[i][j]是将区间[i,j]变成回文序列需要的操作数. if(a ...
- 【bzoj3545】[ONTAK2010]Peaks 线段树合并
[bzoj3545][ONTAK2010]Peaks 2014年8月26日3,1512 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路 ...
- 使用Reachability检测网格
#pragma mark - 网络连接检查 - (void) currentReach { // 网络检测 Reachability *curReach = [Reachability reacha ...
- laravel 查询构造器2
//查询构造器 public function query() { //获取所有的数据 $student = DB::table('student')->get(); var_dump($stu ...
- 洛谷——P1746 离开中山路
P1746 离开中山路 题目背景 <爱与愁的故事第三弹·shopping>最终章. 题目描述 爱与愁大神买完东西后,打算坐车离开中山路.现在爱与愁大神在x1,y1处,车站在x2,y2处.现 ...
- Nginx常用命令(启动/重启/停止/测试配置文件/重新加载配置文件)
Nginx 安装后只有一个程序文件,本身并不提供各种管理程序,它是使用参数和系统信号机制对 Nginx 进程本身进行控制的. Nginx 的参数包括有如下几个: 使用: /usr/local/ngin ...
- Unix操作系统LD_PRELOAD简介
http://blog.csdn.net/ieearth/article/details/49952047 Unix操作系统的动态链接库的知识中,这个功能主要就是用来有选择性的载入Unix操作系统不同 ...
- BS版代码生成器 简介
自用的代码生成器 核心:JdbcTemplate+freemarker 目前支持sqlserver和mysql 演示: 1.首界面 2.读数据库中的所有表 3.打开某数据库下的所有表.视图.存储过程 ...
- js long类型的日期转成Date,字符串StringBuilder拼接
longToDate.js //扩展Date的format方法 Date.prototype.format = function (format) { var o = { "M+" ...