C/C++编程笔记:高级C++知识 |虚拟副本构造器

181 阅读2分钟

在虚拟构造函数中,我们看到了构造对象的方法,该对象的类型直到运行时才确定。是否可以在不知道其确切类类型的情况下创建对象?该_虚拟拷贝构造函数_解决这个问题。

有时我们可能需要从另一个现有对象构造一个对象。精确地,复制构造函数执行相同的操作。新对象的初始状态将基于另一个现有对象状态。从另一个对象实例化一个对象时,编译器将调用复制构造函数。但是,编译器需要具体的类型信息来调用适当的副本构造函数。

#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; // Compiler invokes "copy constructor"// Type of s1 and s2 are concrete to compiler// How can we create Derived1 or Derived2 object// from pointer (reference) to Base class pointing Derived object?return 0;}

如果我们不能决定要从哪种对象类型进行复制,该怎么办?例如,虚拟构造函数根据某些输入在运行时创建类层次结构的对象。当我们想从虚拟构造函数创建的另一个对象中复制构造一个对象时,我们不能使用通常的复制构造函数。我们需要一个特殊的克隆函数,该函数可以在运行时复制对象。

例如,考虑一个绘图应用程序。您可以选择一个已经在画布上绘制的对象,然后粘贴同一对象的另一个实例。从程序员的角度来看,我们无法确定哪个对象将被复制粘贴,因为它是运行时决策。我们需要虚拟副本构造函数来提供帮助。

同样,考虑剪贴板应用。剪贴板可以容纳不同类型的对象,并从现有对象复制对象,然后将其粘贴到应用程序画布上。同样,要复制的对象类型是运行时决策。虚拟副本构造函数填补了这里的空白。请参见下面的示例:

#include <iostream>using namespace std;//// LIBRARY SRARTclass Base{public:Base() { }virtual // Ensures to invoke actual object destructor~Base() { }virtual void ChangeAttributes() = 0;// The "Virtual Constructor"static Base *Create(int id);// The "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);}};// We can also declare "Create" outside Base.// But is more relevant to limit it's scope to BaseBase *Base::Create(int id){// Just expand the if-else ladder, if new Derived class is created// User need not be recompiled to create newly added class objectsif( id == 1 ){return new Derived1;}else if( id == 2 ){return new Derived2;}else{return new Derived3;}}//// LIBRARY END//// UTILITY SRARTclass User{public:User() : pBase(0){// Creates any object of Base heirarchey at runtimeint 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;}// Create objects via the "Virtual Constructor"pBase = Base::Create(input);}~User(){if( pBase ){delete pBase;pBase = 0;}}void Action(){// Duplicate current objectBase *pNewBase = pBase->Clone();// Change its attributespNewBase->ChangeAttributes();// Dispose the created objectdelete pNewBase;}private:Base *pBase;};//// UTILITY END//// Consumer of User (UTILITY) classint main(){User *user = new User();user->Action();delete user;}

_用户_类借助虚拟构造函数创建对象。要创建的对象基于用户输入。Action() 正在复制正在创建的对象并修改其属性。借助_Clone()虚拟函数创建的重复对象,该虚拟函数也被视为_虚拟副本构造函数。_Clone()方法背后的概念是_原型模式的基础

以上就是今天的全部内容了。每日分享小知识,希望对你有帮助~

**另外如果你想更好的提升你的编程能力,学好C语言C++编程!**弯道超车,快人一步!笔者这里或许可以帮到你~

C语言C++编程学习交流圈子,**QQ群【951258402】**微信公众号:C语言编程学习基地

分享(源码、项目实战视频、项目笔记,基础入门教程)

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

编程学习视频分享: