虚拟构造函数

发布于 2024-07-04 15:31:05 字数 38 浏览 5 评论 0原文

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

Is there any need of Virtual Constructors? If so can any one post a scenario?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

记忆消瘦 2024-07-11 15:31:06

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

Virtual constructors dont make sense in C++ . THis is because in C++ constructors do not have a return value . In some other programming languages this is not the case . In those languages the constructor can be called directly and the constructor has a return value . This makes them useful in implementing certain types of desgin patterns . In C++ however this is not the case .

赤濁 2024-07-11 15:31:06

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

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

代码将类似于......

type
  MyMetaTypeRef = class of MyBaseClass;

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

Delphi is one language that supports virtual constructors.

Typically they would be used in a class factory type scenario where you create a meta type i.e. that is a type that describes a type. You would then use that meta type to construct a concrete example of your descendant class

Code would be something like....

type
  MyMetaTypeRef = class of MyBaseClass;

var
  theRef : MyMetaTypeRef;
  inst : MyBaseClass;
begin 
  theRef := GetTheMetaTypeFromAFactory(); 
  inst := theRef.Create(); // Use polymorphic behaviour to create the class
苏璃陌 2024-07-11 15:31:06

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

There are plenty of scenarios, for example if you want to create GUIs for more than one environment. Let's say you have classes for controls (“widgets”) but each environment actually has its own widget set. It's therefore logical to subclass the creation of these widgets for each environment. The way to do this (since, as has been unhelpfully pointed out, constructors can't actually be virtual in most languages), is to employ an abstract factory and the above example is actually the standard example used to describe this design pattern.

[浮城] 2024-07-11 15:31:06

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

In what language? In C++ for example the constructors can not be virtual.

末蓝 2024-07-11 15:31:06

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

The constructor can not be virtual by definition. At the time of constructor call there is no object created yet, so the polymorphism does not make any sense.

温折酒 2024-07-11 15:31:06

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

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

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

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

不过,提到抽象工厂模式的人对于 C++ 和 Java 来说可能更正确。

In C++, there's no reason for constructors to ever be virtual, because they are static functions. That means they're statically bound, so you have to identify the very constructor function you're calling in order to call it at all. There's no uncertainty and nothing virtual about it.

This also means that, no matter what, you need to know the class that your object is going to be. What you can do, however, is something like this:

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

... have a virtual function and call it after constructon. This is a standard pattern in Objective-C, in which first you call the class's "alloc" method to get an instance, and then you call the initilializer that suits your use.

The person who mentioned the Abstract Factory pattern is probably more correct for C++ and Java though.

十秒萌定你 2024-07-11 15:31:06

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

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

有关原因的更完整解释,请参阅 Scott Meyers 撰写的《Effective C++》第三版第 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!

In C++, all constructors are implicitly virtual (with a little extra). That is, the constructor of the base class is called before that of the derived class. So, it's like they're sort of virtual. Because, in a virtual method, if the derived class implements a method of the same signature, only the method in the derived class is invoked.

However, in a constructor, BOTH METHODS ARE INVOKED (see example below).

For a more complete explanation of why this is so, please see Item 9 of Effective C++, Third Edition, By Scott Meyers (Never call a virtual function during construction or destruction). The title of the item may be misleading in relation to the question, but if you read the explanation, it'll make perfect sense.

#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();

}

Output:

Animal Constructor Invoked.
Wolf Constructor Invoked.
-------------
I eat like a wolf!
染年凉城似染瑾 2024-07-11 15:31:05

一如既往:查看 C++ FAQ lite:虚函数

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

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

As always: look up at C++ FAQ lite: virtual functions.

It will explain not only "virtual constructor" but destructors/functions too!

This of course, if you wanted C++ in the first place...

寻找一个思念的角度 2024-07-11 15:31:05

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

If you are talking about virtual destructors in C++ (there isn't any such thing as virtual constructors) then they should always be used if you are using your child classes polymorphically.

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

Edit: Not sure why I've got a downvote for this (would be helpful if you left a comment...) but have a read here as well

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文