【问题标题】:Virtual Constructors虚拟构造函数
【发布时间】:2010-09-09 09:25:40
【问题描述】:

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

【问题讨论】:

  • 您需要为这个问题添加更多信息 - 人们不知道如何回答。
  • 构造函数可以是虚拟的吗?我不这么认为..到目前为止,我们可以在 C++ 中使用虚拟析构函数,但不能使用虚拟构造函数。

标签: virtual constructor scenarios


【解决方案1】:

如果您在谈论 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

【讨论】:

  • ...可能被否决了,因为您的答案虽然正确,但与问题无关。不是我,顺便说一句...
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 构造函数在 Delphi 中确实可以是虚拟的。
    【解决方案4】:

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

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

    代码可能类似于....

    type
      MyMetaTypeRef = class of MyBaseClass;
    
    var
      theRef : MyMetaTypeRef;
      inst : MyBaseClass;
    begin 
      theRef := GetTheMetaTypeFromAFactory(); 
      inst := theRef.Create(); // Use polymorphic behaviour to create the class
    

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

        • 那根本不是真的。构造当然可以是虚拟的,整个想法是能够声明一个基类类型的变量并从不同的具体类构造它。例如,Delphi 是一种允许虚拟构造函数的语言。
        【解决方案7】:

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

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

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

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

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

        【讨论】:

        • 可惜 C++ 类不是对象...... ----------------- 在 C++ 中,构造函数没有理由成为虚拟的,
        【解决方案8】:

        在 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!
        

        【讨论】:

        • “在 C++ 中,所有构造函数都是隐式虚拟的”——我很好奇,您能否指出任何说明这一点的文献。
        • 如上所述,Scott Meyers 书中的第 9 项概述并解释了这一点。一个例外是在虚拟基类中。请参阅 Bjarne Stroustrup 的“C++ 编程语言,特别版”的第 15.2.4.1 节,了解虚拟基类的描述以及“该语言如何确保虚拟基的构造函数只被调用一次”。
        【解决方案9】:

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

        【讨论】:

        • 当您说虚拟构造函数在 C++ 中没有意义时,您是对的。但它可能与返回值无关。
        猜你喜欢
        • 2012-04-13
        • 2012-09-02
        • 1970-01-01
        • 2016-01-22
        • 2015-10-09
        • 2013-05-23
        • 2013-12-30
        • 2012-01-20
        相关资源
        最近更新 更多