Inherit from const class

后端 未结 8 1596
不思量自难忘°
不思量自难忘° 2021-01-12 00:24

I would like to inherit from a class with the const specifier like this:

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

class Co         


        
相关标签:
8条回答
  • 2021-01-12 00:43

    I would like to inherit from a class with the const specifier"

    However much you want to is irrelevant. You cannot. That is not valid C++.

    Can I somehow use the const keyword for inheritance?"

    No.

    0 讨论(0)
  • 2021-01-12 00:48

    I have a trick, not a clean solution.

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

    then

    ConstChild cc;
    cc.set(10); // ERROR
    cc().get();
    
    0 讨论(0)
  • 2021-01-12 00:52

    If you create a const member function set, you will get what you need.

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

    The only caveat is that a sly user can circumvent your intention by using:

    ConstChild child;
    child.set(10);    // Not OK by the compiler
    
    Property& base = child;
    base.set(10);    // OK by the compiler
    
    0 讨论(0)
  • 2021-01-12 00:57

    You can use a template class and a specialization for a constant type:

        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>{ };
    
    0 讨论(0)
  • 2021-01-12 00:57

    I had the same need and I ended up with this quite manual approach :

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

    Note that the using keyword would not work with overloads 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
    };
    

    To solve this you could redefine the function yourself and call the parent :

    class B : private A
    {
    public:
    
        void foo(void) const
        {
            A::foo();
        }
    };
    

    It can become pretty time consuming if you're inheriting a large hierarchy, but if it's for a not-so-big class it should be very reasonable and being quite natural for the user.

    0 讨论(0)
  • 2021-01-12 01:04

    I had the need for a related problem, which is: to really control/highlight mutable and const access on some class. I did it with this simple reusable template wrapper:

    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];
        ...
    }
    
    0 讨论(0)
提交回复
热议问题