c++polymorphismoverloadingreturn-by-reference

Const overloading and polymorphysm


I have an accessor member function (e.g. operator[]) that is const-overloaded:

class Container {

public:
    Foo&       operator[](int i);
    const Foo& operator[](int i) const{
        return const_cast<Container *>(this)->operator[](i);
    }
};

Here, const Foo& operator[] const is defined in this way so that the same thing is not defined twice.

Now I want to make Container a base class, and operator[] becomes virtual:

class BaseContainer {

public:
    virtual Foo& operator[](int i) = 0;
    const Foo& operator[](int i) const{
        // Is this correct?
        return const_cast<BaseContainer *>(this)->operator[](i);
    }
};

class DerivedContainer : public BaseContainer {
public:
    Foo& operator[](int i);
};

Since it is illegal to const_cast from const DerivedContainer * to BaseContainer *, I am not sure if this works in the case of polymorphism.

I would assume that the cast is still valid because the type of this would always be const BaseContainer * in BaseContainer::operator[] const because it is not virtual, but I am not sure if that's the correct way of doing this. Maybe it is simply better to define operator[] twice in this case?


Solution

  • would assume that the const_cast is still valid because the type of this would always be const BaseContainer * in BaseContainer::operator[] const because it is not virtual, but I am not sure if that's the correct way of doing this.

    Your understanding is correct. The code should work as intended.

    There is another thing you have to think about, though. When you declare

    Foo& operator[](int i);
    

    in the derived class, the const version is not going to be found if the function call is made on a derived class object/reference/pointer. To be able to use it with a derived class object/reference/pointer, add the following in the derived class.

    using BaseContainer::operator[];