继承自const类

时间:2016-06-28 21:34:59

标签: c++ inheritance const

我想从具有const说明符的类继承,如下所示:

class Property
{
    int get() const;
    void set(int a);
};

class ConstChild : public const Property
{
    // Can never call A::set() with this class, even if
    // the instantiation of this class is not const
};

class NonConstChild : public Property
{
    // Can call both A::set() and A::get() depending on 
    // the constness of instantiation of this class
};

我的编译器显然在第二个类声明中给出了const关键字的错误。理想情况下,我希望避免创建ReadOnlyProperty将继承的新类ConstChild

我可以以某种方式使用const关键字进行继承吗?

  • 如果没有,您对如何解决这个问题还有其他想法吗?

8 个答案:

答案 0 :(得分:6)

稍后在继承树中引入可变性并适当地派生:

class Property
{
    int get() const;
};
class MutableProperty : public Property {
{
    void set(int a);
};

然后:

class ConstChild : public Property { ... };
class MutableChild : public MutableProperty { ... };

答案 1 :(得分:3)

我需要一个相关的问题,即:真正控制/突出某些类的mutable和const访问。 我用这个简单的可重用模板包装器做到了:

template <typename T>
class TAccessor : private T
{
public:
    const T&    Const() const { return *this; }
    T&          Mutable() { return *this; }
};

// Example of use:
template <typename T>
using MyVector = TAccessor<std::vector<T>>;


void main()
{
    MyVector<int> vector;

    vector.Mutable().push_back(10);

    int x = vector.Const()[1];
    ...
}

答案 2 :(得分:1)

  

我想从具有const说明符“

的类继承

无论你想要多少都无关紧要。你不能。这不是有效的C ++。

  

我可以以某种方式使用const关键字进行继承吗?“

没有

答案 3 :(得分:0)

如果您创建const成员函数set,您将获得所需内容。

class Property
{
    int get() const;
    void set(int a);
};

class ConstChild : public Property
{
    void set(int a) const {}
};

唯一需要注意的是,狡猾的用户可以通过以下方式规避您的意图:

ConstChild child;
child.set(10);    // Not OK by the compiler

Property& base = child;
base.set(10);    // OK by the compiler

答案 4 :(得分:0)

使用数据成员或私有基类而不是公共基类。

然后您可以控制对该成员的访问权限。

如果需要多态行为,可以将Property事物设置为抽象接口。

答案 5 :(得分:0)

您可以使用模板类和常量类型的专门化:

    template<typename T> class base_property {
    protected:
      T value;
    };
    template<typename T> class property : public base_property<T> {
    public:
      const T& get()const { return value; }
      void set(const T& v){ value = v; }
    };

    template<typename T> class property<const T> : public base_property<T> {
    public:
      const T& get()const { return value; }
    };

    class ConstChild : public property<const int>{ };

答案 6 :(得分:0)

我也有同样的需求,最终我得到了这种完全手动的方法:

class A
{
public:

    void fooMutable(void) {}
    void fooConst(void) const {}
};

class B : private A
{
public:

    using A::fooConst;
    const A& getParent(void) const
    {
        return *this;
    }
};

void fooParent(const A&) {}

int main(void)
{
    auto b = B{};
    b.fooConst(); // Ok
    b.fooMutable(); // Fail
    fooParent(b); // Fail
    fooParent(b.getParent()); // Ok

    return 0;
}

请注意,using关键字不适用于重载const / mutable:

class A
{
public:

    void foo(void) {}
    void foo(void) const {}
};

class B : private A
{
public:

    using A::foo; // Expose the const and the mutable version
};

要解决此问题,您可以自己重新定义函数并调用父函数:

class B : private A
{
public:

    void foo(void) const
    {
        A::foo();
    }
};

如果您要继承一个较大的层次结构,这可能会非常耗时,但是如果它用于一个不太大的类,那么它应该非常合理并且对用户来说很自然。

答案 7 :(得分:-1)

我有一个技巧,而不是一个干净的解决方案。

class ConstChild : private Property
{
    operator const Property () { return *this; }
};

然后

ConstChild cc;
cc.set(10); // ERROR
cc().get();