简体   繁体   English

如何从 C++ 中的未命名派生类调用非默认父构造函数?

[英]How to call a non-default parent constructor from an unnamed derived class in C++?

In C++, single use structures and classes can be declared unnamed, if an object is created directly:在 C++ 中,如果直接创建对象,则可以将一次性结构和类声明为未命名的:

struct { int x; int y; } point;

Unnamed classes may also inherit from a base class.未命名的类也可以从基类继承。 This is for example useful to create a list of different "processors" from a base processor interface.例如,这对于从基本处理器接口创建不同“处理器”的列表很有用。 Here a simple example:这里有一个简单的例子:

struct Processor {virtual int op(int a, int b) = 0;};
struct : Processor {int op(int a, int b) override { return a+b; }} Adder;
struct : Processor {int op(int a, int b) override { return a*b; }} Multiplier;

So both Adder and Multiplier become single derived objects of the Processor interface.因此, AdderMultiplier成为Processor接口的单个​​派生对象。 But what, if the base Processor has more structure and has a constructor, that requires parameters?但是,如果基本 Processor 具有更多结构并具有构造函数,那需要参数怎么办? Let's see this example:让我们看看这个例子:

class Processor {
private:
    std::string name;
public:
    virtual int op(int a, int b) = 0;
    const std::string& getName() const { return name; }
    Processor(std::string name) : name(name) {}
};

How does one create an unnamed subclass for this Processor, for example an "Adder".如何为此处理器创建未命名的子类,例如“加法器”。 The naive attempt:天真的尝试:

class : public Processor {
public:
    int op(int a, int b) override { return a + b; }
} Adder { "Adder" };

unfortunately fails, because the unnamed class has no implicitely generated constructor, that would accept "Adder" as its argument.不幸的是失败了,因为未命名的类没有隐式生成的构造函数,它将接受"Adder"作为其参数。 And explicitely declaring such a constructor is not possible, either, because it is not possible to declare constructors in unnamed clases: The constructor is named the same as the class, but if there is no class name, then there is no constructor name, either.并且明确声明这样的构造函数也是不可能的,因为不可能在未命名的类中声明构造函数:构造函数的名称与类相同,但如果没有类名,则也没有构造函数的名称.

I know, that there are easy workarounds: One is to give a name after all (potentially in a namespace) and then use that to declare a constructor.我知道,有一些简单的解决方法:一个是毕竟给一个名字(可能在命名空间中),然后用它来声明一个构造函数。 One might also be tempted to use a virtual init() method, that is called from the constructor of Processor , and which does the work, that the constructor is supposed to do.人们可能还想使用从Processor的构造函数调用的虚拟init()方法,该方法执行构造函数应该执行的工作。 But this doesn't work, as the virtual call in the constructor doesn't reach the method in the derived class, yet.但这不起作用,因为构造函数中的虚拟调用尚未到达派生类中的方法。 But, instead, the call to init() could be hidden in the initializer of a data member of the unnamed class.但是,相反,对init()的调用可能隐藏在未命名类的数据成员的初始化程序中。

But is there any "pure" C++ answer, which keeps the unnamed class unnamed and still does everything in the constructor, that should be done in the constructor?但是是否有任何“纯”的 C++ 答案,它使未命名的类保持未命名并且仍然在构造函数中完成所有应该在构造函数中完成的工作?

While writing this question, I found the answer already, so I will share it here: With C++11, the using keyword was extended to allow the explicit import of the constructors of the base class, and this solves the problem neatly:在写这个问题的时候,我已经找到了答案,所以我在这里分享一下:在 C++11 中, using关键字被扩展为允许显式导入基类的构造函数,这巧妙地解决了问题:

class : public Processor {
using Processor::Processor;
public:
    int op(int a, int b) override { return a + b; }
} Adder { "Adder" };

So Adder is instantiated correctly at program startup and the namespace is kept safe from pollution.因此Adder在程序启动时被正确实例化,并且命名空间不受污染。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM