在c++中模拟虚拟构造函数
在我的应用程序中,我必须从基类派生一些类,问题是我想强制派生类具有 3 个特定的构造函数实现。由于 c++ 没有虚拟纯构造函数,它看起来非常绝望(我必须手动检查每个类的实现以确保特定的构造函数被实现,这不是很有趣)。
昨天我发现了一种疯狂的方法来模拟虚拟演员的行为:
template <class T>
class AbstractEnforcer{
protected:
AbstractEnforcer(){}
private:
static void Enforcer(){
delete new T();
delete new T(*(new unsigned int));
delete new T(*(new unsigned int, *(new QString));
}
}
class AbstractClass : private AbstractEnforcer<AbstractClass>{
}
这种方法的唯一不便之处在于我必须使用以下语法声明所有派生类:
class X : private AbstractEnforcer<X>
即使这不是问题;因为 Enforcer() 方法永远不会被调用(即使如此它也不会执行任何操作[希望如此!!!])
我的问题是: “是否有任何方法(不使用宏)强制派生类使用此机制而不对 AbstractClass 进行参数化(因为这仅在一个派生级别中起作用”
template <class T>
class AbstractClass : private AbstractEnforcer<T>{
}
In my application I have to derive some classes from a base one, the problem is that I want to enforce the derived classed to have 3 particular constructor implementation. As c++ don't have virtual pure constructor, it seemed quite desperate (I had to check manually each class implementation to ensure that the particular ctors are implemented, not quite fun to do).
Yesterday I found a crazy way to simulate the comportment of a virtual ctor:
template <class T>
class AbstractEnforcer{
protected:
AbstractEnforcer(){}
private:
static void Enforcer(){
delete new T();
delete new T(*(new unsigned int));
delete new T(*(new unsigned int, *(new QString));
}
}
class AbstractClass : private AbstractEnforcer<AbstractClass>{
}
the only inconvenience with this approach is that I have to to declare all derived class with the syntax:
class X : private AbstractEnforcer<X>
And even if it's not a problem; because the Enforcer() methode never get called (and even so it does nothing [hope so!!!])
My question is:
"is there any mean (not with macros) to force the derived class to use this mechanism without parametrazing the AbstractClass (because this will work in only one level of derivation"
template <class T>
class AbstractClass : private AbstractEnforcer<T>{
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您的解决方案无法解决问题,因为未实例化未使用的模板化代码,因此除非您手动调用此函数,否则它将不会验证所需构造函数的存在。
您可以做的是从执行器的构造函数中调用此方法:
然后,编译器会抱怨 - 任务完成。
请注意,我已禁用复制构造函数,以便无法绕过该检查(通过调用不同的构造函数)。
编辑 - 非泄漏 Enforcer():[因为绝对不需要在那里使用动态分配..]
Your solution does not solve the problem since templated code that isnt used is not instantiated, and thus unless you manually invoke this function - it will not verify the existence of the wanted constructors.
What you can do is have this method called from the constructor of your enforcer:
Then, the compiler complains - mission accomplished.
Note that I've disabled the copy constructor so that there will be no way to bypass that check (by calling a different constructor).
Edit - Non leaking Enforcer(): [As there's absolutly no need to use dynamic allocations there..]
请参阅 C++ 常见问题解答中的此页面。
我要做的是这样的:
然后每个派生类将被迫重写这些函数,这应该使用不同的构造函数创建新对象。
See this page in the C++ FAQ.
What I would do is something like this:
Then each of the derived classes would be forced to override these functions, which should create new objects with different constructors.
从这个评论到一个答案,我认为你并不是真的想实现你在这里所要求的,而是一件不同的事情。我参考的评论是:
第1部分:
第 2 部分:
您在问题中要求的是 1,您可以通过不同的方式强制执行它,只需阅读一些答案,或者查看元编程示例和 boost::type_traits 库。
现在,如果您真正想要的是第 2 部分:提供动态加载插件机制,那么您不需要强制执行构造函数,而是需要为插件对象和插件对象的创建提供一个通用接口。无法实例化未知(在编译时)对象的实例,这意味着您将无法从代码中调用构造函数。我建议
用户需要提供插件的实现以及创建它们的工厂。他们可能需要为他们的库实现一个入口点,以便您可以访问工厂(或者他们可以在您的系统中注册他们的工厂,否则我建议使用库来实现这些目的(boost::extension似乎是一个值得一看的地方)
From this comment to one of the answers I think that you do not really want to achieve what you are asking here, but rather a different thing. The comment I refer to is:
Part 1:
Part 2:
What you are asking in the question is 1, and you can enforce it in different ways, just read some of the answers, or take a look at metaprogramming examples and the boost::type_traits library.
Now, if what you really want is part 2: provide a dynamic loading plugin mechanism then you do not need to enforce the constructors, but a common interface both for the plugin objects and the creation of the plugin objects. There is no way of instantiating an instance of an object of unknown (at compile time) object, and that means that you will not be able to call the constructors from your code. I would suggest
Users will need to provide the implementation of a plugin and the factory that creates them. They will probably need to implement a point of entry for their library so that you can get access to the factory (or so they can register their factory within your system, or else I would suggest using a library for these purposes (boost::extension seems like a place to look at)
我可能只是有一个用于生成测试的模板:
然后在测试中的某个地方执行以下操作:
这些可能全部放在一起,也可能位于每个类 X、Y、Z 的单独位置。取决于您想要如何组织测试。
如果我使用的值不合适,请输入一些合适的值,或者编译该测试但不运行它。如果您没有单元测试,请获取一些单元测试,或者将以下内容添加到类中(而不是从基类继承):
通常不需要使构造函数成为抽象基类定义的接口的一部分。原因是这样的接口用于动态多态性 - 您将一个对象传递给某个函数,然后它调用它的函数。除了使用模板之外,您不能将类“传递”给函数并让它实例化该类。无论如何,模板大多在编译时强制执行它们的接口 - 如果您实例化模板并且它使用构造函数,那么构造函数必须存在。
I'd probably just have a template for generating a test:
Then somewhere in your tests, do:
Those might be all together, or in separate places for each of the classes X, Y, Z. Depends how you want to organise your tests.
If the values I used aren't suitable, either put in some values which are, or else compile that test but don't run it. If you don't have unit tests either get some, or else add the following to the class (instead of inheriting from the base class):
You don't usually need to make constructors part of an interface defined by an abstract base class. The reason is that such interfaces are for dynamic polymorphism - you pass an object to some function, and it calls functions on it. You can't "pass" a class to a function and have it instantiate the class other than with templates. Templates mostly enforce their interfaces at compile time anyway - if you instantiate the template and it uses the constructor, then the constructor has to be there.
如果您忘记实现构造函数但在代码中使用它,则会出现编译错误。例如:
如果未提供 Derived(int) 构造函数,将出现编译时错误 - 将不会使用 Base 构造函数。
If you forget to implement the constructor but use it in your code, you will get a compilation error. For example:
will be a compile-time error if the Derived(int) constructor is not provided - the Base constructor will not be used.
我最终采用了这个解决方案,但没有放弃:
在每个我不想强制执行的类中,我只是添加这样的内容:
我没有找到任何其他方法来在类中动态注入此代码。而且我可能不清楚这次行动的最终目的(抱歉我的英语很糟糕)。
I finally adopted this solution, but not quit convienced:
and in each class that I wan't to enforce I just add like this:
I didn't find any other way to inject this code dynamically in a class. And I may been unclear about the final purpose of the operation (sorry for my terrible English).