C++ 抽象基类中常量成员变量初始化的通用解决方案
鉴于以下情况C++ 抽象基类中常量成员变量初始化的通用解决方案,c++,inheritance,polymorphism,C++,Inheritance,Polymorphism,鉴于以下情况 class Base { public: Base(double par1, double par2) : par1_(par1), par2_(par2) {} const double value_; protected: const double par1_, par2_; virtual double Calc_Value() = 0; }; class Derived_
class Base
{
public:
Base(double par1, double par2)
:
par1_(par1),
par2_(par2)
{}
const double value_;
protected:
const double par1_, par2_;
virtual double Calc_Value() = 0;
};
class Derived_A : public Base
{
public:
Derived_A(double par1, double par2)
:
Base(par1, par2)
{}
protected:
double Calc_Value()
{
// <code to calc value with par1_ and par2_>
}
};
class Derived_B : public Base
{
public:
Derived_B(double par1, double par2, double par3)
:
Base(par1, par2),
par3_(par3)
{}
const double par3_;
protected:
double Calc_Value()
{
// <code to calc value with par1_, par2_ and par3_>
}
};
int main()
{
std::vector<Base*> my_vector;
// do stuff using polymorphism
}
类基
{
公众:
底座(双par1,双par2)
:
第1部分(第1部分),
par2(par2)
{}
常数双值;
受保护的:
常数双par1,par2;
虚拟双计算值()=0;
};
类派生的\u A:公共基
{
公众:
导出A(双par1,双par2)
:
基础(par1、par2)
{}
受保护的:
双计算值()
{
//
}
};
类派生的_B:公共基
{
公众:
派生_B(双par1,双par2,双par3)
:
基础(par1,par2),
第3部分(第3部分)
{}
常数双参数;
受保护的:
双计算值()
{
//
}
};
int main()
{
std::vector my_vector;
//使用多态性做一些事情
}
这一直困扰着我一段时间。我想在创建Derived\u A
或Derived\u B
的对象时,使用Calc\u value()
初始化value\u。我只知道Base
可以初始化其常量成员。现在,我的类对象主要是一些容器,它们在创建时计算必要的值。所以它们应该是只读的。
我知道我可以使值
不是常数,但这会使它变为可变的。我在互联网上找到的大多数解决方案只是在Base
中创建一个额外的构造函数,但是我必须在基类中声明par3
,这意味着,每次有派生的对象时,它都会有一个par3
成员变量,而不使用它。另外,假设我想要有更多具有不同Calc\u Value()
函数的派生类,那么我是否需要为每个额外的子类声明一个构造函数?到目前为止,我已经克服了这个问题,只需将Calc_Value()
函数public,因此不需要public const成员变量。但在我看来,当通过函数访问对象时,圆括号会降低可读性,这就是为什么我希望在Base
中使用const成员变量的原因
这个问题有一个通用的解决方案吗?您可以在基类中有一个常量double&
,并将该double存储在派生类中。像这样的
#include <iostream>
struct Foo {
Foo(const double& ref) : value(ref) {}
const double& value;
};
struct Bar : Foo {
Bar(const double p1, const double p2) : Foo (value), value(p1 + p2) {}
private:
double value;
};
int main() {
Bar b(5, 3);
Foo* f = &b;
std::cout << f->value;
}
这似乎是为了避免在此时编写()
,而使代码过于复杂。如果它是const
,则必须在构造函数初始值设定项列表中进行初始化。如果value\uu
的值只有派生类知道,为什么它是基类的成员?例如,您可以在Base
中使用纯虚拟的getValue
函数,并让派生类提供值。请注意,要正确使用多态性,您需要在基类中定义一个虚拟析构函数。@Base的supervalue
需要包含计算值,否则myvector[idx]->“值”
不起作用,或者你是什么意思?另外,您是指纯虚拟函数,如Calc\u Value()
but public?我这样做了,但圆括号在我看来降低了可读性,这就是为什么我希望有一个const成员。我只是想知道是否有我不知道的解决办法。我不是一个有经验的程序员。@anastaciu谢谢你的评论!我想,我想做的是不可能的。是的,在我的例子中我忘记了析构函数。
struct Bar : Foo {
Bar(const double p1, const double p2) : Foo (value), value(Calc_value(p1, p2)) {}
private:
static double Calc_value(const double p1, const double p2) {
return p1 + p2;
}
double value;
};