【问题标题】:Access protected data member via friend member function通过好友成员功能访问受保护的数据成员
【发布时间】:2021-01-09 13:53:40
【问题描述】:

编辑:

原程序有多个文件为shown in here

我正在尝试从不同类的朋友成员函数访问我类中受保护的数据成员。

我不断收到访问错误:

9:32:错误:无效使用不完整类型 'class b' 5:7:错误: 成员函数“void b::f(a*)”中“class b”的前向声明: 12:13:错误:'int a::i' 受保护 20:47:错误:在此范围内 上下文

这是我的代码:

// Example program
#include <iostream>
#include <string>

class b;
class a{
    public:
    
    friend void b::f(a* pointer);
    
    protected:
    int i = 6;
    
    
    
};

class b{
    public:
    void f(a* pointer){std::cout<<pointer->a::i<<std::endl;}
    
    
};




int main()
{
  a a1;
  b b1;
  
  b1.f(&a1);
}

【问题讨论】:

  • 要将b::f() 声明为friend,必须已定义类b。一个简单的class b 声明是不够的。
  • @Peter 但是如果两个类是相互依赖的,我该怎么做?
  • 在类 b 的定义之前放置类 a 的声明。然后在a 类之前定义类b,而不是之后。您还需要移动 b::f() 的定义,使其位于类定义之外(不是内联)。
  • "但是如果两个类是相互依赖的,我该怎么做呢?"更改您的设计,使它们不会相互依赖。有很多解决方案,取决于实际目标是什么......

标签: c++ friend-function


【解决方案1】:

这个问题只是表面上与friend 相关。而是由于类定义和成员函数的循环依赖关系; a 需要知道b 的定义,因为它引用了b::f。但是b::f的定义需要a的定义,因为它引用了a::i。幸运的是,类及其成员函数的定义可以相互分离。

您可以采取以下措施逐步解决这个问题:

  1. 声明class a;
  2. 定义class b { /* ... */ };,但定义其成员函数(因为它们需要访问a的定义
  3. 定义class a { /* ... */ };,可能带有内联成员函数定义
  4. 最后定义b的成员函数。

看起来是这样的:

// Step 1:
class a;

// Step 2:   
class b{
    public:
    void f(a* pointer);
};

// Step 3:
class a{
    public:
    friend void b::f(a* pointer);
    
    protected:
    int i = 6;
};

// Step 4:
void b::f(a* pointer)
{
    std::cout<<pointer->a::i<<std::endl;
}

【讨论】:

  • 感谢您的回复。 why it's not working in here?
  • 因为您误解了第 1 步。您的标题中仍然存在循环依赖。 b.h 包含 a.h,但它必须声明 class a; 而不是包含其完整定义。
【解决方案2】:

在您尝试通过friend void b::f(a* pointer); 声明朋友b 的方法时,b 类是不完整的。您还不能引用成员。另一方面,b 只需要 a 的前向声明:

// Example program
#include <iostream>
#include <string>

class a;
class b{
    public:
    void f(a* pointer);                
};

class a{
    public:        
    friend void b::f(a* pointer);        
    protected:
    int i = 6;
};

void b::f(a* pointer){std::cout<<pointer->a::i<<std::endl;}

int main()
{
  a a1;
  b b1;
  
  b1.f(&a1);
}

【讨论】:

    【解决方案3】:

    试试这个。您试图在定义类 b 之前引用 b::f

    // Example program
    #include <iostream>
    #include <string>
    class a;
    
    class b{
        public:
        void f(a* pointer);
    };
    class a{
        public:
        
        friend void b::f(a* pointer);
        
        protected:
        int i = 6;        
    };
    
    void b::f(a* pointer)
    {std::cout<<pointer->a::i<<std::endl;}
    
    
    
    
    
    
    int main()
    {
      a a1;
      b b1;
      
      b1.f(&a1);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-21
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-05
      相关资源
      最近更新 更多