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

C++ 如何使继承层次结构中的成员函数始终返回相同的值?,c++,design-patterns,C++,Design Patterns,我有一个继承层次结构,我想让这个层次结构中的每个类都有一组特定于该类的属性,这些属性在程序运行期间不会改变。例如: class Base { public: const std::string getName() const; bool getAttribute1() const; int getAttribute2() const; }; 现在我希望这些函数始终返回相同的结果。此外,当另一个类继承Base时,这个类应该有自己的属性集,并且这个派生类的任何实例都应该有相

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

class Base
{
public:
    const std::string getName() const;
    bool getAttribute1() const;
    int getAttribute2() const;
};
现在我希望这些函数始终返回相同的结果。此外,当另一个类继承
Base
时,这个类应该有自己的属性集,并且这个派生类的任何实例都应该有相同的属性。每个类的名称也应该是唯一的

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

  • 制作一些锁系统 也就是说,为这些属性提供setter,但当它们被多次调用时,让它们抛出运行时异常

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

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


    我对C++是新的,但是我知道有很多成语和模式来解决像这样的一般问题。你知道吗?

    使它们虚拟化,并对函数应返回的结果进行硬编码:

    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; }
    };
    
    如果您想描述类而不是对象,请使用(种类)特征:

    模板结构属性值;
    模板结构AttributeValue{
    static const std::string name(){返回“BaseName”;}
    };
    模板结构AttributeValue{
    static const std::string name(){return“DerivedName”;}
    };
    //...
    auto-nameBase=AttributeValues::name();
    auto-name派生=AttributeValues::name();
    
    使其虚拟化,并对函数应返回的结果进行硬编码:

    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; }
    };
    
    如果您想描述类而不是对象,请使用(种类)特征:

    模板结构属性值;
    模板结构AttributeValue{
    static const std::string name(){返回“BaseName”;}
    };
    模板结构AttributeValue{
    static const std::string name(){return“DerivedName”;}
    };
    //...
    auto-nameBase=AttributeValues::name();
    auto-name派生=AttributeValues::name();
    
    我有一个继承层次结构,我想让这个层次结构中的每个类都有一组特定于该类的属性,这些属性在程序运行期间不会改变

    那么,只需将相应的值作为参数提供给类构造函数,并且不要在公共接口上公开任何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) { }
    };
    
    这样,您就不会产生虚拟函数调用的开销,并且不必为派生类中的每个成员重写类似的虚拟函数

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

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

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

    你需要更好地思考你想做什么(当然要提到它是什么)。纯虚拟的问题到底是什么?为什么听起来很糟糕?我正在尝试建立遗传算法的层次结构。它们有很多共同点,因此我将它们表示为对象,每个算法都应该有一个唯一的名称。虚拟函数的问题在于,它们返回的值总是与const静态成员返回的值相同,这一点并不是不言自明的。您需要更好地思考您正在尝试做什么(当然还要提及它是什么)。纯虚拟的问题到底是什么?为什么听起来很糟糕?我正在尝试建立遗传算法的层次结构。它们有很多共同点,因此我将它们表示为对象,每个算法都应该有一个唯一的名称。虚拟函数的问题在于,它们总是返回与const静态成员相同的值,这一点并非不言自明。