3

是否需要虚拟构造函数?如果是这样,任何人都可以发布一个场景吗?

4

9 回答 9

8

如果您在谈论 C++ 中的虚拟析构函数(没有虚拟构造函数之类的东西),那么如果您以多态方式使用子类,则应始终使用它们。

class A
{
  ~A();
}

class B : public A
{
  ~B();
}

A* pB = new B();
delete pB; // NOTE: WILL NOT CALL B's destructor

class A
{
  virtual ~A();
}

class B : public A
{
  virtual ~B();
}

A* pB = new B();
delete pB; // NOTE: WILL CALL B's destructor

编辑:不知道为什么我对此投了反对票(如果您发表评论会有所帮助...),但也可以在这里阅读

http://blogs.msdn.com/oldnewthing/archive/2004/05/07/127826.aspx

于 2008-09-16T09:14:35.010 回答
3

一如既往:查看C++ FAQ lite: virtual functions

它不仅会解释“虚拟构造函数”,还会解释析构函数/函数!

当然,如果您首先想要 C++...

于 2008-09-16T09:11:19.620 回答
3

有很多场景,例如,如果您想为多个环境创建 GUI。假设您有控件类(“小部件”),但每个环境实际上都有自己的小部件集。因此,为每个环境子类化这些小部件的创建是合乎逻辑的。做到这一点的方法(因为,正如已经指出的那样,在大多数语言中,构造函数实际上不能是虚拟的),是使用抽象工厂,上面的示例实际上是用于描述这种设计模式的标准示例。

于 2008-09-16T09:25:10.537 回答
2

Delphi 是一种支持虚拟构造函数的语言。

通常,它们将用于创建元类型(即描述类型的类型)的类工厂类型场景中。然后,您将使用该元类型来构建后代类的具体示例

代码将类似于....

type
  MyMetaTypeRef = class of MyBaseClass;

var
  theRef : MyMetaTypeRef;
  inst : MyBaseClass;
begin 
  theRef := GetTheMetaTypeFromAFactory(); 
  inst := theRef.Create(); // Use polymorphic behaviour to create the class
于 2008-09-16T09:24:36.763 回答
1

用什么语言?例如,在 C++ 中,构造函数不能是虚拟的。

于 2008-09-16T09:10:19.793 回答
0

根据定义,构造函数不能是虚拟的。在构造函数调用的时候还没有创建对象,所以多态性没有任何意义。

于 2008-09-16T09:13:07.600 回答
0

在 C++ 中,构造函数没有理由是虚拟的,因为它们是静态函数。这意味着它们是静态绑定的,因此您必须确定要调用的构造函数才能完全调用它。没有不确定性,也没有虚拟的东西。

这也意味着,无论如何,您都需要知道您的对象将成为的类。但是,您可以执行以下操作:

Superclass *object = NULL;
if (condition) {
    object = new Subclass1();
}
else {
    object = new Subclass2();
}
object.setMeUp(args);

...有一个虚函数并在构造后调用它。这是 Objective-C 中的标准模式,首先调用类的“alloc”方法来获取实例,然后调用适合您使用的初始化程序。

不过,提到抽象工厂模式的人可能更适合 C++ 和 Java。

于 2008-09-16T09:48:55.393 回答
-1

在 C++ 中,所有构造函数都是隐式虚拟的(有一点额外的)。也就是说,基类的构造函数在派生类的构造函数之前被调用。所以,就好像它们是虚拟的。因为,在虚方法中,如果派生类实现了相同签名的方法,则只会调用派生类中的方法。

但是,在构造函数中,两种方法都被调用(参见下面的示例)。

对于为什么会这样的更完整的解释,请参阅有效 C++,第三版,由 Scott Meyers 的第 9 条(在构造或销毁期间不要调用虚函数)。该项目的标题可能会与问题相关,但如果您阅读说明,它将完全有意义。

#include <iostream>
#include <vector>

class Animal {

    public:

        Animal(){
            std::cout << "Animal Constructor Invoked." << std::endl;
        }

        virtual void eat() {
            std::cout << "I eat like a generic animal.\n";
        }

        //always make destructors virtual in base classes
        virtual ~Animal() {

        }

};

class Wolf : public Animal {

    public:

        Wolf(){
            std::cout << "Wolf Constructor Invoked." << std::endl;
        }

        void eat() {
            std::cout << "I eat like a wolf!" << std::endl;
        }

};


int main() {

    Wolf wolf;
    std::cout << "-------------" << std::endl;
    wolf.eat();

}

输出:

Animal Constructor Invoked.
Wolf Constructor Invoked.
-------------
I eat like a wolf!
于 2012-07-26T07:33:43.023 回答
-2

虚拟构造函数在 C++ 中没有意义。这是因为在 C++ 构造函数中没有返回值。在其他一些编程语言中,情况并非如此。在那些语言中,可以直接调用构造函数,并且构造函数有一个返回值。这使得它们在实现某些类型的设计模式时很有用。然而,在 C++ 中,情况并非如此。

于 2013-02-20T02:57:02.637 回答