稍后在 C++ 中调用基类构造函数(不在初始值设定项列表中)
我正在继承一个类,我想调用它的构造函数之一。但是,在调用它之前,我必须处理一些内容(不需要基类的任何内容)。有什么方法可以稍后调用它,而不是在初始化列表上调用它?我相信这可以在 Java 和 C# 中完成,但我不确定 C++ 是否可以。
我需要传递给构造函数的数据以后无法重新分配,因此我不能只调用默认构造函数并稍后对其进行初始化。
I'm inheriting a class and I would like to call one of its constructors. However, I have to process some stuff (that doesn't require anything of the base class) before calling it. Is there any way I can just call it later instead of calling it on the initializer list? I believe this can be done in Java and C# but I'm not sure about C++.
The data that I need to pass on the constructor can't be reassigned later, so I can't just call a default constructor and initialize it later.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
根据 @Konrad 的建议,另一种选择是使用静态方法来构造对象,例如:
我发现这在从库扩展类并具有多个要覆盖的参数时很有用。
您甚至可以将构造函数设置为私有
Another option, based on the suggestion from @Konrad is to have a static method to construct the object, e.g.:
Ive found this useful when extending a class from a library and having multiple parameters to override.
You can even make the constructor private
这就是 C++ 中从派生类的初始化列表调用基类构造函数的方式。
This is how base class constructors are invoked in C++ from the initialization list of derived class.
不,你不能。基类构造函数必须在初始化列表中调用,并且必须首先调用。
事实上,如果您省略它,编译器只会隐式添加调用。
C# 和 Java 都不允许这样做。
然而,您可以做的是调用一个方法作为基类构造函数调用的参数。然后在构造函数之前处理:
No, you cannot. The base class constructor must be called in the initializer list, and it must be called first.
In fact, if you omit it there, the compiler will just add the call implicitly.
Neither C# nor Java allow this either.
What you can do, however, is call a method as an argument of the base class constructor call. This is then processed before the constructor:
正如几个人回答的那样,您不能延迟基类构造函数的调用,但是 Konrad 给出了一个很好的答案,很可能会解决您的问题。但是,这确实有其缺点(例如,当您需要使用其计算共享中间结果的值来初始化多个函数时),因此为了完整起见,这是解决固定初始化顺序问题的另一种方法,通过使用它。
给定固定的初始化顺序,如果您可以控制派生类(否则您将如何摆弄其中一个构造函数?),您可以潜入一个私有基,以便它将在另一个基类之前初始化基,然后可以使用私有基已计算的值进行初始化:
my_dirty_little_secret
类是一个私有基,因此the_class
的用户无法使用它,它的所有内容都是也是私有的,具有明确的友谊,仅授予the_class
访问权限。但是,由于它在基类列表中首先列出,因此它将在the_other_base_class
之前可靠地构造,因此无论它计算什么都可以用来初始化它。基类列表中的一个很好的注释有望防止其他人通过重构破坏事物。
As was said by several people answering, you cannot delay the invocation of a base class constructor, but Konrad has given a good answer that might well solve your problem. However, this does have its drawbacks (for example, when you need to initialize several functions with values whose calculations share intermediate results), so just to be complete, here's another way of solving the problem of fixed initialization order, by using it.
Given the fixed order of initialization, if you have control over the derived class (and how else would you come to fiddle with one of its ctors?), you can sneak in a private base so that it is going to be initialized before the other base, which can then be initialized with the private base's already calculated values:
The
my_dirty_little_secret
class is a private base so that users ofthe_class
cannot use it, all of its stuff is private, too, with explicit friendship granting onlythe_class
access to it. However, since it's listed first in the base class list, it will reliably be constructed beforethe_other_base_class
, so whatever it calculates can be used to initialize that.A nice comment at the base class list hopefully prevents from others breaking things by refactoring.
恕我直言,我认为不可能以您提到的方式推迟调用基类构造函数。
IMHO I dont think it is possible to defer calling the base class constructor in the way that you mentioned.
哇,我们都曾经年轻过。这个答案不会起作用,所以不要使用它。出于历史目的而留下的内容。
如果您可以完全控制基类,我建议添加一个受保护的方法来进行类初始化,使其成为虚拟的,并在调用其基类之前将派生类实现细节放入其中:
Wow, we were all young once. This answer won't work, so don't use it. Content left for historical purposes.
If you have full control over the base class, I'd recommend adding a protected method to do the class initialization, make it virtual, and put the your derived class implementation details in it before it calls its base: