子类如何调用父类的构造函数以不同的方式初始化成员变量? [C++]
如何在子类的构造函数中计算子类成员变量的值,然后传递给父类的构造函数?
动机是,如果父类默认构造函数中有大量计算,那么我不想进行这些计算,而只需将它们替换为子类随后计算的计算。
例如:
Car.h
class Car
{
public:
Car();
Car(double Price) ;
...
private:
double price;
double DetermineMarketPrice();
};
Car.cpp
Car::Car()
{
//some other long computation
price = DetermineMarketPrice();
}
Car::Car(double Price)
{
price = Price;
}
...
Porche.h
class Porche : public Car
{
public:
Porche();
...
private:
double price;
double discount;
double fee;
double DetermineMarketPrice();
double RetrieveFee();
double CheckDiscount();
...
};
Porche.cpp
Porche::Porche():Car(price)
{
discount = CheckDiscount();
fee = = RetrieveFee();
price = DetermineMarketPrice() * (1-discount) + fee;
}
在本例中,保时捷的价格尚不清楚。它必须在构造函数中计算。如果我像这样调用父级的构造函数,似乎它只会传递尚未初始化的价格。
传递只能在子类初始化结束时才能知道的成员变量的某些值的好方法是什么???
How can I compute the value of a child class's member variable in it's constructor, and then pass on to the parent's constructor??
The motivation is that, if there's a lot of calculation in the parent class default constructor, then I don't want to have to do those calculation and only have them replaced by those computed by child class right after.
For example:
Car.h
class Car
{
public:
Car();
Car(double Price) ;
...
private:
double price;
double DetermineMarketPrice();
};
Car.cpp
Car::Car()
{
//some other long computation
price = DetermineMarketPrice();
}
Car::Car(double Price)
{
price = Price;
}
...
Porche.h
class Porche : public Car
{
public:
Porche();
...
private:
double price;
double discount;
double fee;
double DetermineMarketPrice();
double RetrieveFee();
double CheckDiscount();
...
};
Porche.cpp
Porche::Porche():Car(price)
{
discount = CheckDiscount();
fee = = RetrieveFee();
price = DetermineMarketPrice() * (1-discount) + fee;
}
In this case, the price of a Porche isn't known yet. It has to be calculated in the constructor. If I call the parent's constructor like this, seems like it would only pass the not-yet-initialized price.
What would be a good way to pass some value of member variables that can only be known at the end of the Child class initialization???
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你不能这样做,基类构造函数首先按照初始化顺序执行,然后再初始化数据成员,并且在执行派生类构造函数的主体之前。如果这些计算成本很高,最好的办法可能是将它们移出构造函数。
编辑:从技术上讲,有一种方法可以解决这个问题,通过创建第二个构造函数,或者使用具有默认参数值的默认构造函数,它可以用于停止基类中的计算,如下所示:
但是,我个人会不推荐将此作为良好的设计实践。据了解,人们希望避免延迟初始化作为一种反模式,但是,对于昂贵的计算,正确完成延迟初始化可能是正确的答案:
You can't do that, the base class constructors are executed first in the initialisation order, before data members are initialised and before the derived class constructor's body is executed. If these are costly calculations, the best thing to do may be moving them out of the constructor.
EDIT: There's technically a way to work around this problem, by creating a second constructor, or having a default constructor with a default parameter value, which can be used to stop the calculations in the base class, like so:
However, I personally would not recommend this as a good design practice. It is understood that one would want to avoid delayed initialization as an anti-pattern, however, for costly calculations, properly done lazy initailization might be the right answer:
很大程度上取决于实际情况,但一种常见的解决方案是
将所有计算卸载到静态成员中,因此您可以编写:
如果(如您的示例所示)您首先必须
在设置变量之前计算其他成员变量
基类。对于像您提出的情况,最简单的解决方案
只是用0初始化基类,然后设置实际的
稍后值。
更一般地说,我想知道你的设计。这不可能是对的
基类和派生类都有一个成员
price
。在最常用的继承中,基类将是
抽象,没有数据成员。但即使情况并非如此,
基类的数据成员在派生类中不重复
类:派生类是否可以任意设置或更改它们
这样,他们就可以受到保护;否则,它们属于基类,并且
仅由基类中的函数(可以称为
来自派生类)。
A lot depends on the actual situation, but one frequent solution is to
offload all of the calculations into a static member, so you can write:
This won't work if (as your example suggests) you first have to
calculate other member variables, before setting the variable in the
base class. For cases like the one you present, the simplest solution
is just to initialize the base class with 0, and then set the actual
value later.
More generally, I have to wonder about your design. It can't be right
that both the base class and the derived class have a member
price
.In the most frequent use of inheritance, the base class will be
abstract, with no data members. But even when this is not the case, the
data members of the base class are not duplicated in the derived
classes: if the derived classes can set or change them in an arbitrary
way, they may be protected; otherwise, they are in the base class, and
only manipulated by functions in the base class (which may be called
from the derived class).
只需将计算代码从构造函数中移至实用函数,例如
CalculatePrice( )
即可。构造该对象,然后调用该函数。Just move the calculation code out of the constructor to a utility function such as
CalculatePrice( )
. Construct the object and then call this function.在父级的构造函数中使用虚拟方法来确定价格。在每个子类中重新定义此方法。
Use an virtual method in the constructor of the parent to determine the price. Redefine this method in each child class.