私有嵌套类c ++的实例

时间:2014-12-19 20:20:11

标签: c++ visual-c++ c++11

我有以下代码

class A
{
private:
    class B
    {
    public:
        void f()
        {
            printf("Test");
        }
    };
public:
    B g() 
    {
        return B(); 
    }
};


int main()
{
    A a;
    A::B b; // Compilation error C2248
    A::B b1 = a.g(); //Compilation error C2248
    auto b2 = a.g(); // OK
    a.g(); // OK 
    b2.f(); // OK. Output is "Test"
}

如您所见,我有A类和私有嵌套类B. 不使用auto我不能在A之外创建A :: B的实例,但是我可以使用auto。 有人可以解释这里有什么问题吗? 我使用VC ++ 12.0,13.0,14.0(总是相同的行为)

2 个答案:

答案 0 :(得分:6)

类型B只能由AA的朋友访问,这意味着其他代码无法引用它。另一方面,模板类型推导甚至适用于私有类型,如果您想在A代码中使用任何形式的模板中的私有类型,则需要使用它。

auto功能基于模板类型扣除,并遵循相同的规则,允许呼叫auto b2 = a.g();

答案 1 :(得分:3)

类型扣除!

当您将私有类(A::B)嵌入到另一个类中时,只有外部类能够创建私有类型A::B的对象。

以下声明正在尝试创建一个您无权访问A::B的对象:

A::B b; // Compilation error C2248
A::B b1 = a.g(); //Compilation error C2248

这是因为在main()函数中,您无法“查看”(或访问)隐藏在A内的私有类。 auto绕过那个。公共函数A::g()能够创建A::B的实例,并将其返回给您。

auto稍后通过推断类型来解决这个问题。当编译器处理推导出auto b2 = a.g();的类型时,它会发现类型为A::B。这是可以的,因为A::g()A的成员函数,并且可以访问A::B

实质上,只有A的成员可以声明A::B,但A::B可以通过A的公共成员推断A::B }。