2012-03-26 56 views
5

给出的样本代码:朋友是否看到基类?

class Base { 
public: 
    bool pub; 
protected: 
    bool prot; 
}; 

class Derived : private Base { 
    friend class MyFriend; 
}; 

class MyFriend { 
    Derived _derived; 

    void test() { 
    // Does standard provide me access to _derived.pub and _derived.prot? 
    cout << "Am I allowed access to this: " << _derived.pub 
     << " and this: " << _derived.prot; 
    } 
}; 

是否是一个朋友给我的所有访问,就好像我是在类中的成员函数我会得到到我的朋友吗?换句话说,我可以得到自从我是朋友以来私下继承的基类的受保护和公共成员吗?

+5

看到,因为你已经去麻烦写上去的示例代码,你试过*编译它*?这种答案会很快暴露在警告/缺乏之中。 – ssube 2012-03-26 19:51:42

+2

@peachykeen:编译器接受什么,标准说什么通常是不同的东西。另外,从理论上讲,示例代码无法捕捉到的细微之处。 – 2012-03-26 20:13:54

+0

@AdrianMcCarthy的确如此。但是,许多编译器会在使用非标准功能时发出警告,如果违反标准和编译器的实现,您将得到一个简短而甜蜜的答案。虽然不是万无一失,但尝试并不会伤害。 – ssube 2012-03-27 13:43:06

回答

6

结合大卫·罗德里格斯的答案 - dribeas和Luchian格里戈雷:

是,在问题中所说的工作,但是,正如大卫指出,受保护的成员不能直接通过基类访问。您只有在通过Derived访问受保护的成员时才能访问,当您通过Base访问时,您无权访问相同的成员。

换句话说,基地的受保护成员被视为派生的私人成员,因此朋友可以看到他们,但是,如果您投给基类,则没有朋友关系,因此受保护的成员不再可访问。

这里是明确的区别的例子:

class MyFriend { 
    Derived _derived; 

    void test() { 
    bool thisWorks = _derived.pub; 
    bool thisAlsoWorks = _derived.prot; 

    Base &castToBase = _derived; 

    bool onlyPublicAccessNow = castToBase.pub; 
    // Compiler error on next expression only. 
    // test.cpp:13: error: `bool Base::prot' is protected 
    bool noAccessToProtected = castToBase.prot; 
    } 
}; 
2

朋友声明将使得MyFriend有权访问继承关系(即对世界其他地方为private),但不会授予其访问受保护基础成员的权限,仅限于公共接口。

void MyFriend::test() { 
    Derived d; 
    Base & b = d;   // Allowed, MyFriend has access to the relationship 
    b.prot = false;  // Not allowed, it does not have access to the base 
} 
1

是的,因为Base的成员也Derived的成员(因为他们没有privateBase)。