如何使继承层次结构中的成员函数始终返回相同的值

How to make a member function in an inheritance hierarchy return always the same value?

本文关键字:返回 成员 继承 何使 层次结构 函数      更新时间:2023-10-16

我有一个继承层次结构,我想让这个层次结构中的每个类都有一组属性,这些属性是该类特有的,并且在程序运行期间不会改变。例如:

class Base
{
public:
    const std::string getName() const;
    bool getAttribute1() const;
    int getAttribute2() const;
};

现在我希望这些函数始终返回相同的结果。此外,当另一个类继承Base时,该类应该具有自己的一组属性,并且该派生类的任何实例都应该具有相同的属性。此外,每个类的名称应该是唯一的。

我想知道一种使它尽可能透明和优雅的方法。到目前为止,我已经考虑了两个我可以使用的想法:

  1. 制作一些锁系统。

即为这些属性提供setter,但是当它们被多次调用时抛出运行时异常。

  1. 将getter设置为纯虚的

在这种情况下,函数的结果不会存储在对象本身中。这将模糊地表明结果取决于动态类型。

这两个主意听起来都很糟糕,所以我需要你的帮助。

我是c++的新手,但我知道有很多习语和模式可以解决像这样的一般问题。你知道吗?

我有一个继承层次结构,我想让这个层次结构中的每个类都有一组属性,这些属性是该类特有的,并且在程序运行期间不会改变

那么,只需提供相应的值作为类构造函数的参数,并且不要在公共接口上公开任何setter方法。这将确保这些值在对象的整个生命周期内保持不变。

为了防止可能改变类成员函数(当然可以访问私有数据)中这些数据成员值的错误,将这些数据成员设置为const。注意,这将强制您在构造函数的初始化列表中初始化这些成员。

class Base
{
public:
    // Forwarding constructor (requires C++11)
    Base() : Base("base", true, 42) { }
    const std::string getName() const { return _s; }
    bool getAttribute1() const { return _a1; }
    int getAttribute2() const { return _a2; }
protected:
    // Constructor that can be called by derived classes
    Base(std::string s, bool a1, int a2)
    : _s(s), _a1(a1), _a2(a2) { }
private:
    const std::string _s;
    const bool _a1;
    const bool _a2;
};

派生类只需用适当的参数构造基子对象:

class Derived : public Base
{
public:
    // Provide the values for the constant data members to the base constructor
    Derived() : Base("derived", false, 1729) { }
};

这样就不会产生虚函数调用的开销,也不必为派生类中的每个成员重写类似的虚函数。

将它们设为虚函数并硬编码函数应该返回的结果:

class Base
{
public:
    virtual const std::string getName() const { return "BaseName"; }
    virtual bool getAttribute1() const { return whatEverAttributeValueYouWant; }
    virtual int getAttribute2() const { return attributeValueHere; }
};
class Derived : public Base {
public:
    virtual const std::string getName() const { return "DerivedName"; }
    virtual bool getAttribute1() const { return whatEverOtherAttributeValueYouWant; }
    virtual int getAttribute2() const { return otherAttributeValueHere; }
};

如果你想描述而不是对象,使用(kind-of) traits:

template<class T> struct AttributeValues;
template<> struct AttributeValues<Base> {
    static const std::string name () { return "BaseName"; }
};
template<> struct AttributeValues<Derived> {
    static const std::string name () { return "DerivedName"; }
};
//...
auto nameBase = AttributeValues<Base>::name ();
auto nameDerived = AttributeValues<Derived>::name ();