【问题标题】:C++ error C2027: use of undefined type 'second' (Friend Class)C++ 错误 C2027:使用未定义类型“秒”(朋友类)
【发布时间】:2015-12-10 16:52:30
【问题描述】:

我正在学习友元函数 (C++),但我不明白为什么这段代码不起作用。我明白了

错误:“错误 C2027:使用未定义的类型‘第二’”。 (第 6 行)

这当然只是一个例子(没用)。我正在尝试使用另一个类的成员函数作为朋友(只是那个函数)。我在网上找到了一些例子。但是在这里的一篇旧帖子中,有人说另一个类的成员函数不能成为一个类的朋友。这是真的吗?

#include<iostream>
using namespace std;
class second;

class test
{
    friend void second::fun(test &);
public:
    int j = 89;
private:
    int t = 12;
};

class second
{
public:
    void fun(test &b)
    {
        cout << "Try " << b.j << endl;
    }
    int a = 29;
private:
    int u = 10;
};

int main()
{
    test b;
    second one;
    one.fun(b);
    return 0;
}

【问题讨论】:

    标签: c++ class friend-function


    【解决方案1】:

    要访问second::fun,需要second 的完整定义。如果您颠倒定义这些类的顺序并改为转发声明test,则可以解决此问题。但同样,b.j 需要定义 test,因此您必须分开并推迟 second::fun 的定义:

    #include<iostream>
    using namespace std;
    class test;
    
    class second
    {
    public:
        void fun(test &b); // test must be declared for using a reference to it
        int a = 29;
    private:
        int u = 10;
    };
    
    class test
    {
        friend void second::fun(test &); // second must be defined to access its member
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    void second::fun(test &b)
    {
        cout << "Try " << b.j << endl;   // test must be defined to access its member
    }
    
    int main()
    {
        test b;
        second one;
        one.fun(b);
        return 0;
    }
    

    【讨论】:

    • 是的。事实上。那么这里唯一的解决方案就是将类分隔在更多文件中?
    • 或者你可以按照我发布的方式获得。
    • 如果第二类实际上是在头文件中声明的,那么您需要将 second::fun 放在 second.cpp 中,或者您需要将 second::fun 留在头文件中 - 但是它需要被声明为内联。
    【解决方案2】:

    尝试以下方法:

    class test;
    
    class second
    {
    public:
        void fun(test &b);
        int a = 29;
    private:
        int u = 10;
    };
    
    class test
    {
        friend void second::fun(test &);
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    void second::fun(test &b)
    {
        cout << "Try " << b.j << endl;
    }
    

    【讨论】:

      【解决方案3】:

      您的代码存在一些问题。对于

      friend void second::fun(test &);
      

      为了工作,编译器必须知道second 是什么。由于它是不完整的类型,您将收到编译器错误。为了解决这个问题,您需要在测试前声明 second。这样做会带来另一个问题

      second::fun(test &b)
      

      使用test。为了解决这个问题,我们将转发声明test,然后声明second。更改后,您需要将实际函数定义移出second,并将其放在test 之后。

      #include<iostream>
      using namespace std;
      class test;
      class second
      {
      public:
          void fun(test &b);
          int a = 29;
      private:
          int u = 10;
      };
      class test
      {
          friend void second::fun(test &);
      public:
          int j = 89;
      private:
          int t = 12;
      };
      
      void second::fun(test &b)
      {
          cout << "Try " << b.j << endl;
      }
      
      int main()
      {
          test b;
          second one;
          one.fun(b);
          return 0;
      }
      

      Live Example

      【讨论】:

        【解决方案4】:

        当编译器读取这一行时

        friend void second::fun(test &);
        

        它不知道第二个类是否确实有数据成员fun。为了确保这一行是正确的,编译器需要类 second 的定义。

        另一方面,函数fun的定义必须知道类test有数据成员j

        要解决碰撞,您可以编写以下方式

        #include<iostream>
        using namespace std;
        
        class test;
        
        class second
        {
        public:
            void fun(test &b); // class test is already declared above
            int a = 29;
        private:
            int u = 10;
        };
        
        class test
        {
            friend void second::fun(test &); //class second is already defined above
        public:
            int j = 89;
        private:
            int t = 12;
        };
        
        void second::fun(test &b)
        {
            cout << "Try " << b.j << endl; // class test is already defined above
        }
        
        int main()
        {
            test b;
            second one;
            one.fun(b);
            return 0;
        }
        

        【讨论】:

        • 我试过了,但在这种情况下出现以下错误:错误 1 ​​错误 C2061:语法错误:标识符 'test',错误 2 错误 C2245:不存在的成员函数 'second::fun' 指定为朋友(成员函数签名与任何重载都不匹配),错误 3 错误 C2511:'void second::fun(test &)':在 'second' 中找不到重载的成员函数,错误 4 错误 C2660:'second::fun' : 函数不接受 1 个参数
        • @user5507798 查看我更新的代码。你需要在第二个类之前声明类测试
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-15
        • 1970-01-01
        相关资源
        最近更新 更多