在虚拟构造函数习语中,有一些虚拟函数使用虚拟函数返回新对象或对象的副本。但是要以多态方式调用这些虚函数,您必须使用实际构造函数创建该类的对象。
在设计模式上下文中,这意味着客户端在使用多态对象创建方式之前就知道对象的类型?
在虚拟构造函数习语中,有一些虚拟函数使用虚拟函数返回新对象或对象的副本。但是要以多态方式调用这些虚函数,您必须使用实际构造函数创建该类的对象。
在设计模式上下文中,这意味着客户端在使用多态对象创建方式之前就知道对象的类型?
客户不一定要知道具体类型。例如,考虑这个层次结构:
struct Base
{
virtual ~Base();
virtual Base * clone() const = 0;
static Base * create(std::string const &);
// ...
};
struct A : Base { A * clone() const { return new A(*this); } /* ... */ };
struct B : Base { B * clone() const { return new B(*this); } /* ... */ };
struct C : Base { C * clone() const { return new C(*this); } /* ... */ };
Base * Base::create(std::string const & id)
{
if (id == "MakeA") return new A;
else return new C;
};
在这种情况下,客户端可以像这样创建和复制现有对象:
Base * p = Base::create("IWantB"); // or std::unique_ptr<Base> !
Base * q = p->clone();
在这两种情况下,客户端都不知道*p
or的动态类型*q
。
class Base
{
public:
Base() { }
virtual ~Base() { }
// The "Virtual Constructor"
static Base *Create(int id);
// The "Virtual Copy Constructor"
virtual Base *Clone() = 0;
};
Base *Base::Create(int id)
{
if( id == 1 )
{
return new Derived1;
}
}
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;
}
Base *Clone()
{
return new Derived1(*this);
}
};
当你这样做时,现在在 Main
void main()
{
cout << "Enter ID (1, 2 or 3): ";
cin >> input;
Base *pBase = Base::Create(input);
Base *pCopy = CreateCopy(pBase);
//Dont know what object is created but still access functions thru base pointer
}
Base *CreateCopy(Base *pBase)
{
return pBase->Clone();
}
客户端不需要知道它继承的类的类型,但仍然调用一些函数。
客户端不知道派生类型的虚拟构造函数习语。这个习语的全部目的是通过基指针克隆对象。这是一个例子:
class base
{
public:
base* clone()
{
// NVI: implemented by derived classes.
do_clone();
}
protected:
virtual base* do_clone = 0;
};
class derived : public base
{
protected:
virtual derived* do_clone()
{
// Implementation. Note the return value is not base*.
}
};
有关详细信息,请参阅这篇 ACCU 文章:http: //accu.org/index.php/journals/522