1

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

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

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

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

  1. 做一些锁系统。

那就是为这些属性提供设置器,但是当它们被多次调用时,它们会引发运行时异常。

  1. 使 getter 成为纯虚拟的。

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

这两个想法听起来都非常糟糕,所以我需要你的帮助。

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

4

2 回答 2

4

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

好吧,那么只需将相应的值作为参数提供给类构造函数,并且不要在公共接口上公开任何 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) { }
};

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

于 2013-03-29T09:55:09.707 回答
2

使它们成为虚拟并硬编码函数应返回的结果:

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; }
};

如果您想描述而不是对象,请使用(种类)特征:

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 ();
于 2013-03-29T09:49:37.487 回答