0

I have a class C that privately inherits B that implements an interface A, as shown below:

class A {
public:
    virtual void f() = 0;
    virtual void g() = 0;
};

class B: public A {
public:
    void f() override {};
    void g() override {};
};

class C: private B {
public:
    using B::f; 
};

My intention is that I want C to act like B, but only have access to B::f() and not B::g().

I also have a function that take references to A:

void use(A& a) {} // function that takes any object that inherits from A

My problem is that calling use() with a C object raises the following compilation error:

conversion to inaccessible base class "A" is not allowed

What is the correct way to allow C to be converted into an A?

octopod
  • 824
  • 2
  • 10
  • 23
  • Once the class hierarchy is set, there is little or no need for up-casting, down-casting and side-casting. In fact, you probably do not ever need to use `dynamic_cast`. – Ron May 12 '20 at 12:55
  • 1
    I'm surprised the code compiles – Mike Vine May 12 '20 at 12:55
  • I tried on MSVC 2017 and got: `example.cpp (27): error C2243: 'type cast': conversion from 'C *' to 'A &' exists, but is inaccessible Compiler returned: 2` So your code doesn't compile. Which version of MSVC are you using. Are you _sure_ it actually compiles? Link [here](https://godbolt.org/z/W5BhcE) – Mike Vine May 12 '20 at 13:00
  • Only a `friend` or member function of `C` can call `use()` and pass it the address of a `C`. The purpose of private inheritance is preventing any other function from converting a `C*` to a (pointer to) a private base. You could, notionally, supply `C` with an `operator A *()` but, if you do that, you are defeating the point of using private inheritance - so might as well use `public` inheritance. – Peter May 12 '20 at 13:06
  • Put this in C: `A& as_A() { return *this; }` – Eljay May 12 '20 at 13:08
  • What compiler (and version) are you using? – Ted Lyngmo May 12 '20 at 13:09
  • You forgot ````virtual````. Pure functions should be virtual. – A M May 12 '20 at 15:11
  • @ArminMontigny Thanks. Sorry I forgot to include that but I edited it. – octopod May 12 '20 at 17:42
  • @TedLyngmo g++ 7.3.0 (MinGW) on Windows and g++ 7.4.0 on Ubuntu. It compiles on both. – octopod May 12 '20 at 17:44
  • @octopod Ok, strange. That's not behavior of g++ 7.3 or 7.4 on godbolt. Is it Ubuntu WSL (on Windows) or a standard Ubuntu? – Ted Lyngmo May 12 '20 at 17:56
  • Can C not inherit B publically but override g() so that it does nothing? – stackoverblown May 12 '20 at 18:37
  • 1
    Sorry. I'm aware the example code doesn't compile and I'll try to see if I can get it working. I tried to isolate the problem from an actual project I'm working on and turn it into a small example but I guess it backfired haha. – octopod May 12 '20 at 19:15
  • The Ubuntu in question is Ubuntu 20.04 running in a VM. I guess I could make it so g() does nothing, but I wanted to have it so attempting to call g() causes a compilation error. – octopod May 12 '20 at 19:17
  • I've concluded that it really shouldn't compile and I'm somehow just "getting lucky" in my actual case. I'll take this extra problem out of the question since it seems irrelevant now. – octopod May 12 '20 at 19:30
  • "_I guess it backfired_" - :-) The power of the [mcve] strikes again! – Ted Lyngmo May 13 '20 at 08:51

0 Answers0