C++私有继承和静态成员/类型

Wea*_*key 6 c++ inheritance static

我试图阻止一个类能够将其"this"指针转换为其中一个接口的指针.我通过中间代理类使用私有继承来做到这一点.问题是我发现私有继承使得层次结构中继承类下的所有类都无法访问所有公共静态成员和基类类型.

class Base
{
public:
    enum Enum
    {
        value
    };
};

class Middle : private Base
{ 
};

class Child : public Middle
{
public:
    void Method()
    {
        Base::Enum e = Base::value; // doesn't compile BAD!     
        Base* base = this; // doesn't compile GOOD!
    }
};
Run Code Online (Sandbox Code Playgroud)

我已经在VS2008(所需版本)和VS2010中都尝试过这种方法,但都不行.

谁能想到一个解决方法?或者采用不同的方法来停止转换?

此外,我是行为的好奇心,它只是编译器实现的副作用,还是设计?如果按设计,那么为什么呢?我一直认为私有继承意味着没有人知道中继继承自Base.但是,所展示的行为意味着私有继承意味着更多,事实上,Child比不在类层次结构中的任何命名空间更少访问Base!

Jam*_*lis 6

您应该能够Base::Enum通过完全限定来访问它:

class Child : public Middle
{
public:
    void Method()
    {
        ::Base::Enum e = ::Base::value;
    }
};
Run Code Online (Sandbox Code Playgroud)

这是语言指定的行为(C++03§11.2/ 3):

注意:私有基类的成员可能无法作为继承的成员名称访问,但可以直接访问.

接下来是一个扩展示例,它与您的示例代码有效相似.

但是,似乎Visual C++ 2008和Visual C++ 2010都没有正确实现这一点,因此虽然您可以使用该类型::Base::Enum,但仍然无法访问::Base::value.(实际上,Visual C++似乎已经犯了很多错误,因为它错误地允许你使用不完全合格的Base::Enum).

要"解决"问题,您可以使用声明添加到Middle类中:

class Middle : private Base
{ 
protected:

    using Base::Enum;
    using Base::value;
};
Run Code Online (Sandbox Code Playgroud)

这会不会让你使用Base::EnumBase::value在您的Child类,但它可以让你使用EnumvalueMiddle::EnumMiddle::value.