首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >部分隐藏继承树

部分隐藏继承树
EN

Stack Overflow用户
提问于 2014-04-07 21:36:07
回答 2查看 67关注 0票数 1

我有一个这样的类树:

代码语言:javascript
复制
class A;
class B : public A;

然后,我想创建一个从B类派生出来的类,但我希望对外部成员以及从类C继承的任何其他成员隐藏该派生。

代码语言:javascript
复制
class C : private B;

void test() {
    C c;
    B *b = &c; // compiler error: B in C is private and is therefore not type compatible. This is desired.
}

但是,我也想揭示A类的继承,在这种情况下,隐藏类B也隐藏了A类。

代码语言:javascript
复制
void test2() {
    C c;
    A *a = &c; // Compiler error: A is only accessible through B which is not possible with a private inheritance of B. This is not desired; this conversion should be possible.
}

我可以再次从A继承,但这显然会创建重复的成员变量,如果A有任何。我可以创建A类的虚拟继承,但是我不认为它会产生我想要的确切效果,因为这会影响整个树,而不是这个片段(对吗?)

我认为显而易见的解决方案是创建一个类型转换成员函数:

代码语言:javascript
复制
class C : private B {
    A * turn_into_A() {
        // Since B is an A and we are still in the scope of C, this will succeed
        return this;
    }
};

然而,我宁愿避免显式的类型,比如那种情况,

任何理智的人都会告诉我我做错了。他们可能是对的。但我想知道的是,仅仅是为了知识的缘故:是否有一种没有虚拟继承或显式成员函数类型化的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-24 14:44:41

我找到了一个可行的解决方案:

代码语言:javascript
复制
class A {
public:
    void somethingA() {
        std::cout << "a" << std::endl;
        return;
    }
 };
class B :
    public A {
public:
    void somethingB() {
        std::cout << "b" << std::endl;
        return;
    }
};
class C :
    private B {
public:
using B::A; // While B is private (and hidden), this exposes access to B::A
    void somethingC() {
        std::cout << "c" << std::endl;
        return;
    }
};

int main(int argc, char **argv) {
    C c;
    B* b = &c; // Compiler error: cannot convert because B is private (desired)
    A* a = &c; // Okay! (required)
    c.somethingC();
    c.somethingB(); // Compiler error: private. (desired)
    c.somethingA(); // Compiler error: A is exposed, but not A's members. This can be solved by adding 'using B::A::somethingA()' in class declaration (undesired but acceptable in my situation)
    a->somethingA(); // Okay! (of course)
}

它并不完美,因为它只将C暴露为能够转换为A(就我的目的而言,这就是我最终要做的事情,所以这很好)。但是,它并不直接公开A的成员以允许C作为-an-A使用(如不能调用c::somethingA(),除非您还专门公开了B::A:somethingA。

票数 0
EN

Stack Overflow用户

发布于 2014-04-08 07:23:39

继承描绘了一种是一种关系。所以,在你的对象模型中,B是- A,C是-A,B,那么,为什么不使用

代码语言:javascript
复制
class C : public B { ...};

这样您就可以将C对象看作B对象,也可以视需要将A对象视为A对象。希望这能有所帮助。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22923581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档