如何在 C++ 中获得多态行为构造函数?
我有一个基类,我希望它看起来像这样:
class B
{
// should look like: int I() { return someConst; }
virtual int I() = 0;
public B() { something(I()); }
}
重点是强制派生类重写 I
并强制在构造每个对象时调用它。这用于做一些簿记,我需要知道正在构造什么类型的对象(但我否则将当前对象视为基类)。
这是行不通的,因为 C++ 不允许您从构造函数调用抽象虚函数。
有没有办法获得相同的效果?
基于这个链接似乎答案是没有办法得到我想要的东西。然而它说的是:
简短的回答是:不。基类不知道它派生自哪个类,这也是一件好事。
[...]
也就是说,在构造函数 Derived1::Derived1 开始之前,该对象不会正式成为 Derived1 的实例。
但就我而言,我不想知道它是什么,而是想知道它会变成什么。事实上,我什至不关心我得到什么,只要用户可以(事后)将其映射到一个类。所以我什至可以使用像返回指针这样的东西并摆脱它。
(现在回到阅读该链接)
I have a base class that I want to look like this:
class B
{
// should look like: int I() { return someConst; }
virtual int I() = 0;
public B() { something(I()); }
}
The point being to force deriving classes to override I
and force it to be called when each object is constructed. This gets used to do some bookkeeping and I need to know what type of object is being constructed (but I otherwise treat the current object as the base class).
This doesn't work because C++ won't let you call an abstract virtual function from the constructor.
Is there a way to get the same effect?
Based on this link it would seem that the answer is there is no way to get what I want. However what it says is:
The short answer is: no. A base class doesn't know anything about what class it's derived from—and it's a good thing, too.
[...]
That is, the object doesn't officially become an instance of Derived1 until the constructor Derived1::Derived1 begins.
However in my case I don't want to know what it is but what it will become. In fact, I don't even care what I get back as long as I the user can (after the fact) map it to a class. So I could even use something like a return pointer and get away with it.
(now back to reading that link)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您不能从构造函数中调用虚方法(或者更准确地说,您可以调用它们,但最终会从当前正在构造的类中调用成员函数)。是派生对象此时还不存在。您对此无能为力,从构造函数多态调用虚拟方法根本不可能。
您应该重新考虑您的设计 - 例如,将常量作为参数传递给构造函数。
有关详细信息,请参阅 C++ 常见问题解答。如果您确实想在构造过程中调用虚函数,阅读此内容。
You can't call virtual methods from the constructor (or to be more precise, you can call them, but you'll end up calling the member function from the class currently being constructed)., the problem is that the derived object does not yet exist at that moment. There is very little you can do about it, calling virtual methods from the constructor polymorphically is simply out of the question.
You should rethink your design -- passing the constant as an argument to the constructor, for example.
See C++ faq for more. If you really want to call virtual functions during construction, read this.
也许对每个派生类型使用静态工厂方法?这是在 .NET 中构造奇异对象(即具有非常具体的初始化要求的对象)的常用方法,我对此表示赞赏。
在基本构造函数中调用虚拟方法通常是不受欢迎的,因为您永远无法确定特定方法的行为,并且(正如其他人已经指出的那样)派生构造函数尚未被调用。
Perhaps use a static factory method on each derived type? This is the usual way to construct exotic objects (read: those with very specific initialisation requirements) in .NET, which I have come to appreciate.
Calling virtual methods in base constructors is generally frowned upon, as you can never be certain of a particular method's behaviour, and (as somebody else already pointed out) derived constructors will not have yet been called.
这将不起作用,因为执行基类构造函数时派生类还不存在:
相反,您可以将参数添加到基类构造函数:
或者如果您真的喜欢 OOP,您还可以创建几个附加类:
That will not work as the derived class does not yet exist when the base class constructor is executed:
Instead you could add the arguments to the base class constructor:
Or if you're really fond of OOP you could also create a couple of additional classes:
您需要的是两阶段构建。使用通用程序员的治疗方法:添加另一层间接层。
What you need is two-phase construction. Use the Universal Programmer's cure: Add another layer of indirection.