C++ 选择性遗传C++;

C++ 选择性遗传C++;,c++,inheritance,C++,Inheritance,您能解释一下为什么下面的代码可以编译并且运行良好(在gcc-4.3.4中检查)。我认为选择性继承不能削弱甚至加强对成员/方法的访问。它不违反封装规则吗 #include <iostream> class A { protected: void foo() { std::cout << "foo" << std::endl; } }; class B : private A { public: using A::foo; //foo()

您能解释一下为什么下面的代码可以编译并且运行良好(在gcc-4.3.4中检查)。我认为选择性继承不能削弱甚至加强对成员/方法的访问。它不违反封装规则吗

#include <iostream>

class A {
protected:
    void foo() { std::cout << "foo" << std::endl;  }
};

class B : private A {
public:
    using A::foo;   //foo() becomes public?!
};

int main() {
    B b;
    b.foo();
    return 0;
}
#包括
甲级{
受保护的:

void foo(){std::cout从语言的角度来看,这没有什么错(是否是好的设计是另一回事)

任何类都可以选择向更广泛的受众公开它可以访问的内容

原则上,您的示例与以下示例无异:

class B : private A {
public:
    void bar() { foo(); }
};
除了这里的
foo()
是由代理公开的


您不能做的恰恰相反:公共派生类不能限制对可通过基类访问的内容的访问。

+1教我一些东西。您可以在从标准容器私下继承时这样做。基本上,您禁止向上转换(这意味着您不需要虚拟析构函数),但您允许一些繁琐的操作重新实现/转发。当然可以;在
struct A{int i;};struct B:A{private:using A::i;}
名字
B::i
别名和阴影
A::i
具有私人访问权限。当然,这不会阻止您编写
B.A::i
,这可能就是您的意思。@ecatmur:
B
可以混淆事物,但它不能限制访问。我可以始终向上转换对
A&
的引用,并使用
A
的API:
A&A=b;A.i=42;
@ecatmur:hide一词的选择有点不幸。我改进了措辞。@NPE:Access是静态检查的,就像在ecatmur的示例中,你可以向上转换以获得访问权限一样,你可以向上转换为松散访问权限。这与混淆无关,但与基本原则有关语言是构建的。设计是否好是另一个问题=>例如,在
std::vector
中添加一个方法可能会很有用,而我通常建议使用自由函数,因为有些人不愿意这样做(靠对象生或死…)在这种情况下,
private
继承+方法转发允许模拟混合。