标题说明了。 Parent
公开公开Grandparent
,我希望在Child
中公开,但我想隐藏Parent
本身。我不明白为什么这不可能,但我找不到使用using
指令来实现这一目标的方法。如果我可以使用using
公开公开私有继承的成员变量,我希望能够为私有继承的基础做同样的事情,但我似乎无法找到它的语法。 Child
中的显式转换运算符可能有效,但有更简洁的方法吗?
class Grandparent {};
class Parent: public Grandparent {};
class Child: Parent
{
// How can I expose Grandparent here publicly?
};
void takeGrandparent( Grandparent const & );
int main()
{
takeGrandparent( Child() ); // error: cannot cast 'Child' to its private base class 'Grandparent'
}
UPD:因为人们问我为什么需要这个,这是我的用例。 Grandparent
是Parent
实现的接口。我希望Child
使用Parent
来实现并提供此界面,但另外保持Parent
私有。
答案 0 :(得分:1)
您也可以直接继承Grandparent
。这需要virtual
继承,通常是多重继承的情况。
class Grandparent {};
class Parent: virtual public Grandparent {};
class Child: Parent, virtual public Grandparent
{
// No special treatment needed, interface is inherited automatically
};
这实际上在私有继承的概念中是有意义的。您可能会将私有继承视为"我太懒了,无法将Parent
成员添加到Child
,因此我将使用继承来实现它"。如果你这样做"正确"使用组合,它变得更像是具有委托的常规代码:
class Grandparent
{
public:
virtual int GrandparentMethod() {return 8;}
};
class Parent: public Grandparent {};
class Child: public Grandparent
{
public:
virtual int GrandparentMethod() {return parent.GrandparentMethod();}
private:
Parent parent;
};
答案 1 :(得分:0)
不,没有“更清洁”的方式。
公共继承表示is-a关系,而private不表示。一旦您标记了Child
不是Parent
,您丢失的所有声明都表示Child
是Grandparent
- 您打破了传递链。将Child
设置为Grandparent
的唯一方法是也从Grandparent
继承它 - 但我很确定你不想走这条路。
答案 2 :(得分:0)
在Child
方面实施Parent
存在概念性问题,但仅将其设为Grandparent
:
这意味着Parent
的契约被打破,这意味着Child
的实施与Parent
的实施细节密切相关。我们使用抽象和封装将我们从这些细节中分离出来是有原因的。
否则,您只需将Child
设为Parent
。
因此,C ++从未添加任何语法来允许此操作。
答案 3 :(得分:0)
class Grandparent {
public:
virtual void foo() = 0;
};
class Parent: public Grandparent {
public:
virtual void foo() final { std::cout << "Dance!\n"; }
};
template<class D>
struct proxy_Grandparent:Grandparent {
virtual void foo() final {
return proxy().foo();
}
private:
D* self() { return static_cast<D*>(this); }
D const* self() const { return static_cast<D const*>(this); }
decltype(auto) proxy() {
return self()->get_proxy();
}
};
class Child: Parent,
public proxy_Grandparent<Child>
{
friend class proxy_Grandparent<Child>;
private:
Parent& get_proxy() { return *this; }
};
其中有两份Grandparent
;如果Grandparent
是一个界面,那么这一切都不会有问题。
实际上,您应该将Parent
继承更改为完全has-a:
class Child:
public proxy_Grandparent<Child>
{
friend class proxy_Grandparent<Child>;
private:
Parent parent;
Parent& get_proxy() { return parent; }
};