2

I have two classes defined this way :

Classes

class A {
    A(A& a) { ... } // deep copy
    <dtor + methods>
protected:
    A(std::shared_ptr<AImpl>& pp) : p(pp) { /* empty */ }
    std::shared_ptr<AImpl> p; // the only member variable of A
}
class B : public A {
    explicit B(const A& a) : A(a.p) { /* empty */ } // KO
    // OR
    explicit B(const A& a) { p = a.p; } // KO
    // OR
    explicit B(const A& a) : p(a.p) { /* empty */ } // obviously KO
    <members, ...>
}

Note:

A(A& a) is doing a deep copy of the object pointed by p, which is not what I need, so I implemented A(std::shared_ptr<AImpl>&) to initialize A::p with a copy of the shared pointer itself to share the ownership.

I cannot define a setter for A::p because AImpl must not be a public type and must remain in the scope of class A or its subclasses only (interface-implementation classes separation design).

Issue:

I have a compilation error with all constructor flavors mentioned above, saying that p is not accessible because it is protected in base class, but why?

A. Gille
  • 912
  • 6
  • 23

1 Answers1

1

You're trying to access A::p not of the base of B, but of another object, when access is prohibited.

You could instead provide a protected constructor:

class A {
    A(A& a) { ... } // deep copy
    <dtor + methods>
protected:
    A(const A& a, int) : p(a.p) { /* empty */ }
    std::shared_ptr<AImpl> p; // the only member variable of A
};

class B : public A {
    explicit B(const A& a) : A(a,0) { /* empty */ }
    <members, ...>
};
Walter
  • 44,150
  • 20
  • 113
  • 196