我用这种方式定义了两个类:
课程
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, ...>
}
注意:
A(A& a)
正在对p
所指向的对象进行深层复制,这不是我所需要的,因此我实现了A(std::shared_ptr<AImpl>&)
以初始化A::p
>共享指针本身的副本以共享所有权。
我无法为A::p
定义一个setter,因为AImpl
不能是公共类型,并且必须保留在类A
或其子类的范围内(接口实现类分离设计)。
问题:
我在上面提到的所有构造函数风格中都遇到了编译错误,说p
不可访问,因为它在基类中受保护,但是为什么?
答案 0 :(得分:1)
在禁止访问的情况下,您尝试访问的不是A::p
基址的B
,而是另一个对象。
您可以改为提供受保护的构造函数:
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, ...>
};