c ++派生的基类Friend函数在Parent上访问private?

时间:2016-04-26 17:48:29

标签: c++ inheritance visual-c++ friend

请考虑以下情况:

    class A 
    { 
     friend void B::Itemfunction();
     private:
     int number;
     int size;
     public:
     Randomfunction();
    }

    class B : public A
    {
     private:
     string Random;
     public:
     void Itemfunction();
     void CheckLog();

    }

类型A的Itemfunction中生成的对象是否可以访问obj的私有数据成员?如:

    void B::Itemfunction(){
    A obj;
    //Possible to do...
    obj.number = 2;
    }

我理解派生类B可以访问A的所有公共部分,但是如果我只想要一个函数(Itemfunction)来访问私有部分,那么这是正确的方法吗?我只是想看看我的理解是否正确。

干杯

3 个答案:

答案 0 :(得分:1)

在您实现{ id: yada, name: yada, bar.version: yada, bar.changed: yada } 的代码中,您将在本地创建一个类型为Itemfunction的新的完全不相关的对象。在继承中,您的A对象具有类型为B的内部子对象。您可以直接在A内访问A的字段。但是,您无法访问私人成员。你的友情伎俩不会奏效;在看到B定义之前,您无法声明B朋友的方法,但在B定义之前无法定义B,并且您可以看到我们进入圈子。你可以做的是让该成员受到保护:

A

答案 1 :(得分:1)

不,这是不可能的。对于尚未完全声明的类,您不能为类成员函数提供帮助。

在这种情况下唯一的方法(因为class B需要一个完全声明的class A继承),就是转发声明class B;并为全班同学:

#include <iostream>
#include <string>

    class B;

    class A 
    { 
     // friend void B::Itemfunction();
     friend class B;
     private:
     int number;
     int size;
     public:
     void Randomfunction();
    };

    class B : public A
    {
     private:
     std::string Random;
     public:
     void Itemfunction();
     void CheckLog();

    };

int main()
{   
}

Live Demo

答案 2 :(得分:0)

这有鸡和蛋的问题。必须为B完全定义A,才能看到B::Itemfunction

class A
{
    friend void B::Itemfunction(); <-- Itemfunction does not exist yet
private:
    int number;
    int size;
public:
    int Randomfunction();
};

class B: public A
{
private:
    std::string Random;
public:
    void Itemfunction();
    void CheckLog();

};

交换订单无效,因为B需要将A定义为从A继承。

class B: public A <-- A does not exist yet
{
private:
    std::string Random;
public:
    void Itemfunction();
    void CheckLog();

};

class A
{
    friend void B::Itemfunction();
private:
    int number;
    int size;
public:
    int Randomfunction();
};

解决方案1是前向定义class B,因此编译器知道B存在,即使它对它一无所知,然后friend整个类,因为A只知道{{} 1}}存在。保持OP的B关系。

friend

但是!所有class B; <-- forward definition of B class A { friend class B; <-- friending all of B, not just the function private: int number; int size; public: int Randomfunction(); }; class B: public A { private: std::string Random; public: void Itemfunction(); void CheckLog(); }; 现在都可以完全访问所有B。如果A想要保留A或任何其他成员隐藏并受其控制,那就很难了。 size可以调用B的所有函数并更改所有A的成员变量。 A可以完全展开B

这也不能扩展到其他子类。 A可以查看B的所有内容,但AC不能。

所以说你有一个不那么简单的例子,D不允许任何人弄乱A的价值。也许它是内部数组的容量,而更改size将导致size运行超过已分配内存的末尾。这里的原因并不重要;为了这个例子,除了A之外,不允许任何人改变A

这引导我们解决方案2:protected access和访问者功能。

size

class A { protected: <-- all inheritors can access members in this block. No one else can int number; private: <-- only A can access members in this block int size; public: int Randomfunction(); int getSize() <-- accessor function to provide read-only access to size { return size; } }; class B: public A { private: std::string Random; public: void Itemfunction(); <-- can do anything to number and read size void CheckLog(); <-- so can this }; class C: public A { private: std::string member; public: void doStuff(); <-- and this void DoOtherStuff(); <-- and this }; B可以访问C,并可以使用A::number查看A::getSize的值。 sizenumber可以更改B,但C不能更改size。如果您担心调用函数来阅读size的成本,请不要这样做。当编译器完成A::getSize时,您甚至不知道它在那里。可能不是。