朋友类对象可以在其成员函数中访问派生类对象上的基类私有成员吗?

Posted

技术标签:

【中文标题】朋友类对象可以在其成员函数中访问派生类对象上的基类私有成员吗?【英文标题】:Can a friend class object access base class private members on a derived class object in its member function? 【发布时间】:2018-03-20 22:21:11 【问题描述】:

派生类D d的对象如何在Base B的朋友类中被访问?

既然DF 之间没有关系,那么怎么可能 访问朋友类中D对象的私有成员b_var

#include <iostream>
#include <string>
using namespace std;

class B               //Base class
    int b_var;
    friend class F;
;

class D : public B     //Derived Class
    int d_var;
;

class F               //This class is a friend class of B
public:               //So it should access objects of B Not Derived Class 
    void func(D &d)       // object LIke in example d    
        d.b_var = 5;
        cout << "I accessed D's Private Member b_var :" << d.b_var;
    
;

int main()

    cout << "fine";

【问题讨论】:

b_var 仍然是 friends F 类的成员。继承与它无关,请注意d_var 将无法访问F @George:你确定“b_var 仍然是 F 好友类的成员”吗? b_var 是私有的,我认为 private 成员不可继承。 @Raindrop7 是的,我确定。如果private 成员不可继承,那么继承将毫无用处,因为父级的任何私有状态都会丢失。 @George 不!我不同意。派生的子类不能访问基类的私有数据。 (基类的私有数据不是派生类的一部分)。 【参考方案1】:

既然 D 和 F 之间没有关系,那么如何访问朋友类中 D 对象的私有成员 b_var 呢?

F 可以访问类D 的基类B,因为它是一个公共基类。此外,F 可以访问B 的私人成员,包括b_var,因为FB 的朋友。因此,F 可以访问 b_var,它是 D 类的基类 B 的成员。

也许它有助于可视化使用更合格的名称查找的可访问性。 d.b_vard.B::b_var 相同。

【讨论】:

但是 C++ 中的友谊是不可继承的。那么如何从F访问d.b_var呢? @Raindrop7 友谊不可继承是无关紧要的。 F 不需要成为D 的好友,因为它已经是B 的好友,而b_varB 的成员。 @Raindrop7 怎么了?我可以证明F 可以 访问d_var。这是因为d_var不是B的成员,所以FB之间的友谊关系与访问d_var无关。密切注意d_varb_var 之间的区别。它们看起来非常相似。 @Raindrop7 我确实是这么说的。它不会与其他任何东西冲突,不是吗? @Raindrop7 你是在为自己争取积分吗?这个答案和你的一样好,而且直截了当,所以我不明白你的 cmets 最后,你的答案大多是一样的无论如何,但几个小时后......【参考方案2】:

这里发生的是 F 类是 B 类的朋友,这意味着它可以完全访问其成员; private, protected, public.

D 类是 B 类的子类,它继承了 A 类但 private 成员的所有成员。因此,尝试访问私有基类成员将发出错误,例如:

class D : public B
    void func()
        std::cout << b_var << std::endl; // error cannot access private members
    
;

如您所见,D 派生自B,但无法访问b_var,因为它是private

如果你声明孩子是父母的朋友,你可以让它访问它:

class B
    int b_var;
    friend class D;
;

class D : public B
    public:
        void func()
            cout << b_var; // ok now! because D is friend of its parent then it has access to its private data.
        

在您的示例中,类 D 是类 B 的子类,因此它无法访问 b_var,因为它是私有的。但是F 类拥有对B 类的完全访问权限,因此它可以访问其private, public, protected 成员:

class B
    int b_var = 10;
    friend class F;
;

class D : public B
    int d_var;
;

class F
    public:
        void func(D d)
            cout << d.b_var; // it is a hack to encapsulation here

            B b;
            cout << b.b_var << endl; // ok here because F is friend of B.
        
;

正如您在上面看到的,F 拥有对 B 类的完全访问权限,它使用 D 对象并授予它此权限。通常D 无法访问B 私有数据,但F 授予对它的访问权限。

友谊不是传递的(你朋友的朋友不是你的朋友) 友谊不会遗传(你朋友的孩子不是你的朋友) 友谊不是可交换的(做我你的朋友并不一定要做你我的朋友)。

【讨论】:

我明白你@Raindrop7 在说什么。但这里的问题是 d 是 Derived 类的对象。朋友 F 与派生类对象没有联系。这就是为什么我认为 b_var 在作为 D 类的对象的 F 类中无法访问。

以上是关于朋友类对象可以在其成员函数中访问派生类对象上的基类私有成员吗?的主要内容,如果未能解决你的问题,请参考以下文章

C++中的派生类,可以不定义对象直接调用基类的成员和调用自己的成员函数嘛???

protectedpublicprivate

C++ 类 访问限制

无法从派生类构造函数参数访问受保护的基类成员[重复]

指向派生对象的基类指针的 C++ 排序容器

<继承问题>可以把基类对象赋值给子类对象么?