如何在其构造函数中计算子类的成员变量的值,然后传递给父的构造函数?
动机是,如果父类默认构造函数中有很多计算,那么我不想进行那些计算,只是将它们替换为子类后面计算的那些。
例如:
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;
}
在这种情况下,尚未知道保时捷的价格。它必须在构造函数中计算。如果我这样调用父的构造函数,看起来它只会传递尚未初始化的价格。
传递一些只能在Child类初始化结束时知道的成员变量值的好方法???
答案 0 :(得分:5)
很大程度上取决于实际情况,但一个常见的解决方案是 将所有计算卸载到静态成员中,因此您可以编写:
Porsche::Porsche()
: Car( calclulatePrice() )
{
// ...
}
如果(如您的示例所示)您首先必须这样做,这将无效 在设置变量之前计算其他成员变量 基类。对于像您提出的那样的案例,最简单的解决方案 只是用0初始化基类,然后设置实际 价值以后。
更一般地说,我不得不怀疑你的设计。这不可能是正确的
基类和派生类都有一个成员price
。
在最常使用的继承中,基类将是
抽象,没有数据成员。但即使不是这样,也是如此
基类的数据成员在派生中不重复
classes:如果派生类可以在任意中设置或更改它们
他们可能受到保护;否则,他们在基类中,并且
只能由基类中的函数操作(可以调用它)
来自派生类)。
答案 1 :(得分:4)
您不能这样做,在初始化数据成员之前和执行派生类构造函数的主体之前,首先在初始化顺序中执行基类构造函数。如果这些是昂贵的计算,那么最好的办法就是将它们从构造函数中移出。
编辑:技术上有一种方法可以解决这个问题,通过创建第二个构造函数,或者使用默认构造函数和默认参数值,可以用来停止基类中的计算,如下所示:struct SkipCalculatePrice {};
class Car {
public:
Car();
protected:
Car(SkipCalculatePrice);
};
class Ferrari: public Car {
public:
Ferrari(): Car(SkipCaluclatePrice()) [...]
[...]
但是,我个人不会建议这是一个好的设计实践。据了解,人们可能希望避免延迟初始化作为反模式,但是,对于昂贵的计算,正确完成延迟初始化可能是正确的答案:
class Car {
virtual double calculatePrice();
bool priceCalculated;
double price;
public:
double getPrice() {
if(!priceCaluclated) {
price = calculatePrice();
}
return price;
}
}
class Ferrari: public Car {
double calculatePrice();
};
答案 2 :(得分:1)
只需将计算代码从构造函数移动到实用程序函数,例如CalculatePrice( )
。构造对象,然后调用此函数。
答案 3 :(得分:-1)
在父级的构造函数中使用虚方法来确定价格。在每个子类中重新定义此方法。