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的super
value
需要包含计算值,否则
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;
};