C++ - 在派生类中静态初始化基类保护的成员变量

标签 c++ constructor static

我们正在我们的项目中尝试使用有界原始类型,我们可以在其中检查派生类的实例是否具有有效范围内的数据值(minmax 成员变量,在派生 class 的基 class 中受到保护。

我的问题是,有没有一种方法可以静态初始化派生类的 minmax 变量,每个派生的 class 只需一次,而不是每次我实例化派生的

C# 中,这将在静态初始化 block 中,但我不确定如何在 C++ 中执行此操作。

我知道我可以在派生的类构造函数中初始化它们,但每次都这样做似乎很浪费。

我想我正在寻找抽象数据成员,在基类中声明,但随后在派生类中静态定义。

class BoundedFloat
{
public:
    BoundedFloat(const float v) : Value(v) {}

    // some common methods that use Min and Max
    // prefer to implement in base class rather than in each derived class

    bool withinBounds();
    bool breachedLowerThreshold();
    bool breachedUupperThreshold();


protected:
    const float Min;
    const float Max;
    float Value;
}


bool BoundedFloat::withinBounds()
{
    return ((Value >= Min) && (Value<= Max));
}

bool BoundedFloat::breachedLowerThreshold()
{
    return (Value < Min);
}

bool BoundedFloat::breachedUupperThreshold()
{
    return (Value > Max);
}

class Temperature : public BoundedFloat
{
public:
   Temperature(const float v) : BoundedFloat(v) {}

   // seems wasteful to do this each time, when min and max only need 
   // initialised once per derived class
   // Temperature(const float v) : BoundedFloat(v, -40.0f, 80.0f)

   // statically initialise Temperature's Min and Max in base class here somehow?

private:
    // I know this is wrong, but it indicates the functionality I'm looking for.
    override static float Min;
    override static float Max;
}

最佳答案

我认为除了进行一些重新设计外,没有任何方法可以完全按照您的要求进行操作。请记住,对于未标记为 static 的成员,类类型的每个对象都有自己的这些成员拷贝。如果您有多个类型为 Temperature 的对象,每个对象都有自己的 MinMax,因此所有这些对象都需要在某个时候进行初始化。此外,基类 BoundedFloat 无法知道它被用于几个可能的派生类中的哪一个,除非你以某种方式让它知道,并且只传递最小值和最大值可能是最简单的方法“让它知道”。

但是与此相关的“浪费”(编码和维护工作?CPU 运行时?成员变量使用的内存?)对我来说似乎并不那么大。

不过,您可能需要考虑一些重新设计的选项:

  • 将数据从成员更改为虚拟 getter 函数。

    class BoundedFloat
    {
    public:
        BoundedFloat(const float v) : Value(v) {}
        virtual ~BoundedFloat() = default;
    
    protected:
        BoundedFloat(const BoundedFloat&) = default;
        BoundedFloat(BoundedFloat&&) = default;
        BoundedFloat& operator=(const BoundedFloat&) = default;
        BoundedFloat& operator=(BoundedFloat&&) = default;
    
        float Min() const = 0;
        float Max() const = 0;
        float Value;
    };
    
    class Temperature : public BoundedFloat
    {
    public:
       Temperature(const float v) : BoundedFloat(v) {}
    
       float Min() const override { return -40.0f; }
       float Max() const override { return 80.0f; }
    };
    

    现在每个派生类都单独负责其最小/最大值。尽管这种方法有其自身的成本,这对您来说可能重要也可能不重要。

  • 享元模式

    class BoundedFloat
    {
    protected:
        struct Data {
            float Min;
            float Max;
        };
    
        BoundedFloat(const float v, const Data& data_in)
            : Value(v), data(data_in) {}
    
    protected:
        BoundedFloat(const BoundedFloat&) = default;
        BoundedFloat(BoundedFloat&&) = default;
        BoundedFloat& operator=(const BoundedFloat&) = default;
        BoundedFloat& operator=(BoundedFloat&&) = default;
    
        float Value;
        const Data& data;
    };
    
    class Temperature : public BoundedFloat
    {
    public:
        Temperature(const float v) : BoundedFloat(v, my_data) {}
    
    private:
        static const Data my_data;
    };
    
    const Temperature::Data Temperature::my_data{ -40.0f, 80.0f };
    

    这里只有一个派生类数据值的初始化,它们几乎自然地“在”基类中;只需将它们命名为 data.Mindata.Max。当每个类都有大量数据时,通常会使用此模式,但您当然也可以只使用少量数据。这里的编码成本与传递单个基值相当,或者可能更低,并且程序的运行时成本可能会有所上升或下降,具体取决于。

关于C++ - 在派生类中静态初始化基类保护的成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55495264/

相关文章:

c++ - 使用模板模板参数时出错

VB.NET:Windows 窗体的默认构造函数在哪里?

有和没有主体的 C++ 部分构造函数表现不同

c# - 为什么 StreamReader Constructor (String) 不符合构造函数指南?

c++ - C 和 C++ 中的静态和外部全局变量

c++ - 将指针传递给指向函数的指针时出现段错误

c++ - 如何使用同一个函数C++实例化多个线程

static - 使用 Libtool 将静态库强制链接到共享库

c++ - 为什么需要在初始化时指定外部/静态变量的类型?

C++继承设计: avoid member duplication