Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer to base class method with protected inheritance

I have this code:

class Foo
{
public:
    int x = 4;
    int & operator[](size_t index) { return x; }
};

class Bar : protected Foo
{
public: 
    using Foo::operator[];

    Bar () { x++; }
};

int main(int agrc, char ** argv)
{
    typedef int &(Bar::*getOp)(size_t index);

    Bar b;
    auto bVal = b[4];
    getOp o = &Bar::operator[]; 
    auto bVal2 = (b.*o)(7);
}

However, I cannot compile this, because

error C2247: 'Foo' not accessible because 'Bar' uses 'protected' to inherit from 'Foo'

Why is this not possible, when I have used using and I can call operator directly? Is there any way around?

If I change inheritance to public, it is working.

Note: This is just an example of larger class. I dont want to use public inheritance, because I dont want to be able to do Foo f = Bar() because in Bar, I am hiding parent methods (I have not use virtual).

like image 331
Martin Perry Avatar asked May 16 '19 13:05

Martin Perry


People also ask

How do you inherit base class as protected?

public inheritance makes public members of the base class public in the derived class, and the protected members of the base class remain protected in the derived class. protected inheritance makes the public and protected members of the base class protected in the derived class.

When you inherit a class protected variables of the base class is available to?

If the derived class inherits the base class in public mode, protected members of base class are protected members of derived class. public data members of base class are public members of derived class.

When the inheritance is protected the public methods in base class are?

1) Public Inheritance: Protected members of Base class remain protected in Derived class. c. Public members of Base class remain public in Derived class. So, other classes can use public members of Base class through Derived class object.

What will happen to the protected members of the base class when inherited with private keyword in the derived class?

Private Inheritance − When deriving from a private base class, public and protected members of the base class become private members of the derived class.


2 Answers

Why is this not possible, when I have used using and I can call operator directly?

The using declaration gives you access to the name operator[]. But it doesn't alter the member's type. It stays int &(Foo::*)(size_t). Note the Foo.

So converting to the declared type of o requires a conversion down the inheritance tree. This conversion must check that the target class is indeed derived from the base, but that is an inaccessible base.

One way to work around it is to give Bar a member function that returns that pointer. Inside Bar's scope the base will be accessible to the conversion. Also, this sort of conversion requires a static_cast.

like image 165
StoryTeller - Unslander Monica Avatar answered Oct 20 '22 00:10

StoryTeller - Unslander Monica


This conversion is not allowed once the base class Foo is inaccessible.

Instead of using using Foo::operator[], maybe this can solve your problem:

int& operator[](size_t index) { // now a Bar::operator[], not Foo:: anymore
    return Foo::operator[](index);
}
like image 39
João Paulo Avatar answered Oct 20 '22 00:10

João Paulo