C++构造与析构(17) - virtual拷贝构造函数
来源:互联网 发布:linux vi中搜索字符串 编辑:程序博客网 时间:2024/05/26 05:51
在上一篇文章中介绍了实现"virtual constructor"的方法。点击此链接。
有没有可能在不知道类的类型的情形下创建一个对象?
有没有可能在不知道类的类型的情形下创建一个对象?
众所周知,拷贝构造函数是用一个已经存在的对象,来构造一个新的对象。新对象的初始状态取决于已存在对象的状态。当使用一个对象初始化另一个对象时,编译器会调用拷贝构造函数。但是,编译器需要知道确切的类型信息才能调用拷贝构造函数。
#include <iostream>using namespace std; class Base{public:}; class Derived : public Base{public: Derived() { cout << "Derived created" << endl; } Derived(const Derived &rhs) { cout << "Derived created by deep copy" << endl; } ~Derived() { cout << "Derived destroyed" << endl; }}; int main(){ Derived s1; Derived s2 = s1; // 编译器会调用拷贝构造函数 // s1和s2的类型对于编译器是具体的/确切知道的。 // 基于基类指针或引用(指向的是子类对象),如何创建Derived1或Derived2对象? return 0;}如果用户无法确定对象的类型,此时如何使用拷贝构造函数?例如virtual constructor在运行时期间创建了一个对象。当使用拷贝构造函数创建对象时,如果已存在对象是virtual constructor创建的,我们无法使用拷贝构造函数。需要自定义一个在运行时可以拷贝对象的函数。
假设存在这样的例子,一个绘图程序。它支持从已有的图案进行拷贝-粘贴。从程序员的角度看,我们无法知道哪个图案会被拷贝-粘贴,因为它是一个运行时的行为。在这种情况下,就需要使用virtual copy constructor来帮助。
类似地,对于一个记录板程序,从已存在对象拷贝,然后粘贴。具体对象类型是运行时的行为,无法提前知道。就需要使用virtual copy constructor了。参见下面例子:
#include <iostream>using namespace std; //// LIBRARY SRARTclass Base{public: Base() { } virtual ~Base() { } // 确保调用子类析构函数 virtual void ChangeAttributes() = 0; // 做为"Virtual Constructor" static Base *Create(int id); // 做为"Virtual Copy Constructor" virtual Base *Clone() = 0;}; class Derived1 : public Base{public: Derived1() { cout << "Derived1 created" << endl; } Derived1(const Derived1& rhs) { cout << "Derived1 created by deep copy" << endl; } ~Derived1() { cout << "~Derived1 destroyed" << endl; } void ChangeAttributes() { cout << "Derived1 Attributes Changed" << endl; } Base *Clone() { return new Derived1(*this); }}; class Derived2 : public Base{public: Derived2() { cout << "Derived2 created" << endl; } Derived2(const Derived2& rhs) { cout << "Derived2 created by deep copy" << endl; } ~Derived2() { cout << "~Derived2 destroyed" << endl; } void ChangeAttributes() { cout << "Derived2 Attributes Changed" << endl; } Base *Clone() { return new Derived2(*this); }}; class Derived3 : public Base{public: Derived3() { cout << "Derived3 created" << endl; } Derived3(const Derived3& rhs) { cout << "Derived3 created by deep copy" << endl; } ~Derived3() { cout << "~Derived3 destroyed" << endl; } void ChangeAttributes() { cout << "Derived3 Attributes Changed" << endl; } Base *Clone() { return new Derived3(*this); }}; Base *Base::Create(int id){ //如果新的Derived类加入,只需要在此添加if-else. //User类不需要重新编译即可支持新加的对象。 if( id == 1 ) { return new Derived1; } else if( id == 2 ) { return new Derived2; } else { return new Derived3; }}//// LIBRARY END class User{public: // 运行时期间创建Base对象 User() : pBase(0) { int input; cout << "Enter ID (1, 2 or 3): "; cin >> input; while( (input != 1) && (input != 2) && (input != 3) ) { cout << "Enter ID (1, 2 or 3 only): "; cin >> input; } // 调用"Virtual Constructor"来创建对象 pBase = Base::Create(input); } ~User() { if( pBase ) { delete pBase; pBase = 0; } } void Action() { // 赋值当前对象 Base *pNewBase = pBase->Clone(); pNewBase->ChangeAttributes(); delete pNewBase; } private: Base *pBase;}; int main(){ User *user = new User(); user->Action(); delete user;}User类使用virtual constructor创建一个对象。这个对象取决于user input。 函数Action()会拷贝已存在对象给新对象,并修改新对象的属性。使用虚函数Clone()来创建新对象的过程,即被称为virtual copy constructor. 这里使用Clone()方法的这种概念,就属于设计模式中的"原型模式prototype pattern".
0 0
- C++构造与析构(17) - virtual拷贝构造函数
- 构造函数,析构函数与virtual
- C++构造与析构(16) - virtual构造函数
- C++构造与析构(2) - 拷贝构造函数
- 拷贝构造函数与析构顺序
- srting的类构造函数、析构函数、拷贝构造函数与赋值构造函数
- 【C++】拷贝构造函数
- C++:拷贝构造函数
- c++"拷贝构造函数
- C++: 拷贝构造函数
- 【C++】拷贝构造函数
- c++::拷贝构造函数
- 【C++】:拷贝构造函数
- 【C++】拷贝构造函数
- C++:拷贝构造函数
- 【C++】基础知识—构造函数与拷贝构造函数
- <C++>14.构造函数的重载与拷贝构造函数
- C++:析构函数、对象生命周期、类型转换构造、拷贝构造、拷贝赋值、深浅拷贝
- android 上传数据到FTP注意点
- C++构造与析构(16) - virtual构造函数
- JS实现对DOM元素事件的绑定
- 高并发高负载网站系统架构
- 数组指针
- C++构造与析构(17) - virtual拷贝构造函数
- skpye 4.3 installation and configuration in linux CentOS 7 / RHEL 7 / Fedora 20
- 使用 CXF 做 webservice 简单例子
- VIM使用学习笔记 : 按键说明
- C++构造与析构(18) - 静态对象(static object)何时销毁
- 卡永久QQ飞车紫钻 记录
- android中TypedValue.applyDimension()介绍
- Codeforces Round #304 (Div. 2)
- OpenERP 的XML-RPC的轻度体验+many2many,one2many,many2one创建方式