C ++私有继承和静态成员/类型 [英] C++ private inheritance and static members/types

查看:125
本文介绍了C ++私有继承和静态成员/类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to stop a class from being able to convert its 'this' pointer into a pointer of one of its interfaces. I do this by using private inheritance via a middle proxy class. The problem is that I find private inheritance makes all public static members and types of the base class inaccessible to all classes under the inheriting class in the hierarchy.

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!
    }
};

我在VS2008(所需版本)和VS2010中都尝试过这种方法,但都无法正常工作。

I've tried this in both VS2008 (the required version) and VS2010, neither work.

有人能想到解决方法吗?或者另一种停止转换的方法?

Can anyone think of a workaround? Or a different approach to stopping the conversion?

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

Also I am curios of the behavior, is it just a side effect of the compiler implementation, or is it by design? If by design, then why? I always thought of private inheritance to mean that nobody knows Middle inherits from Base. However, the exhibited behavior implies private inheritance means a lot more than that, in-fact Child has less access to Base than any namespace not in the class hierarchy!

推荐答案

您应该能够完全访问 Base :: Enum 符合条件:

You should be able to access Base::Enum by fully qualifying it:

class Child : public Middle
{
public:
    void Method()
    {
        ::Base::Enum e = ::Base::value;
    }
};

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

This is the behavior specified by the language (C++03 §11.2/3):


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

Note: A member of a private base class might be inaccessible as an inherited member name, but accessible directly.

接下来是一个扩展示例,它与您的示例代码实际上类似。

This is followed by an extended example that is effectively similar to your example code.

然而,它出现了Visual C ++ 2008和Visual C ++ 2010都没有正确实现这一点,所以当你可以使用类型 :: Base :: Enum 时,你仍然无法访问 ::基地::值。 (实际上,Visual C ++似乎已经犯了很多错误,因为它错误地允许你使用不完全限定的 Base :: Enum )。

However, it appears that neither Visual C++ 2008 nor Visual C++ 2010 correctly implements this, so while you can use the type ::Base::Enum, you still can't access ::Base::value. (Actually, Visual C++ seems to have gotten a lot of this wrong, as it incorrectly allows you to use the not-fully-qualified Base::Enum).

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

To "get around" the problem, you can add using declarations to the Middle class:

class Middle : private Base
{ 
protected:

    using Base::Enum;
    using Base::value;
};

这不允许你使用 Base :: Enum Child 类中的$ c>或 Base :: value ,但它允许您使用 Enum value Middle :: Enum Middle :: value

This won't let you use Base::Enum or Base::value in your Child class, but it will allow you to use an Enum and value or Middle::Enum and Middle::value.

这篇关于C ++私有继承和静态成员/类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆