类成员函数当友元函数,编译错误

发布于 2021-11-25 05:35:44 字数 2004 浏览 688 评论 4

1.环境:Win7 + codeBlock + gcc

2.问题:友元函数报错

--------------

G:projectsfriendFun2A.h|11|error: 'B' has not been declared|
G:projectsfriendFun2A.h||In member function 'void B::bPrint(A)':|
G:projectsfriendFun2A.h|14|error: 'int A::m_A' is private|
G:projectsfriendFun2B.cpp|17|error: within this context|
||=== Build finished: 3 errors, 0 warnings ===|

--------------

代码分为A.h,A.cpp,B.h,B.cpp,main.cpp

A.h


#ifndef A_H
#define A_H

#include "B.h"

class A
{
    public:
        A(int );
        virtual ~A();
        friend void B::bPrint(A aa);
    protected:
    private:
        int m_A;
};

#endif // A_H

B.h


#ifndef B_H
#define B_H


#include "A.h"


class B
{
    public:
        B();
        virtual ~B();
        void bPrint(A aa);
    protected:
    private:
};


#endif // B_H

B.cpp


#include "B.h"
#include <iostream>


using namespace std;
B::B()
{
    //ctor
}


B::~B()
{
    //dtor
}


void B::bPrint(A aa)
{
    cout << "in B :" << aa.m_A << endl;
}

A.cpp没什么好说的。


但是如果和在一个main.cpp的话,就没有上面的问题


#include <iostream>


using namespace std;
class A;


class B
{
    public:
        void bPrint(A aa);
};


class A
{
    public:
        friend void B::bPrint(A aa);
        A(int a):m_A(a){};
    private:
        int m_A;
};


void B::bPrint(A aa)
{
    cout << "in B :" << aa.m_A << endl;
}


int main()
{
    B b;
    A a(6);
    b.bPrint(a);
    return 0;
}




如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

温柔少女心 2021-11-29 00:06:24

看Primer的时候发现这个问题。

然后百度到下面这个顺序:

先声明A -> 定义B类 -> 定义A类 -> 定义友元函数.

但A和B类不在一个文件时,就悲剧了。

C++大神帮忙看看

冷默言语 2021-11-28 20:21:34

用你的方法改后编译通过了。 非常感谢! 顺便问一下,预编译#include "A.h"这个可以认为会调用A的定义吗?

夜司空 2021-11-27 13:51:14

回复
include这个东西一定不要和类联系起来,更多的是应该是类似复制粘贴的行为。用gcc -E展开宏调用应该可以帮助你理解(电脑上没gcc,我也不太确定参数对不对)

想挽留 2021-11-27 03:31:03

首先你需要了解不完整的类型的概念,要不然你根本不明白那个顺序的原理。

不完整的类型指的是那种声明了,但是缺少具体定义的类型。比如你最后一段代码第5行。

这时候重要的是,什么时候可以用不完整的类型,什么时候不可以用。

你最后一段代码第11行,这部分是声明,所有A是不完整的类型,所以无所谓。

18行,这里B必须是完整的类型,否则B的成员函数是访问不了的。

25-28行,这里的实现需要A是完整的类型,所以必须放在A的定义之后。

所以是这样的:

#ifndef A_H
#define A_H
 
#include "B.h"

class A
{
    public:
        A(int a) : m_A(a) {};
        virtual ~A() {};
        friend void B::bPrint(A aa);
    protected:
    private:
        int m_A;
};
 
#endif // A_H

A.h不用改,为了编译,直接补上了实现。

#ifndef B_H
#define B_H
 
 
class A;
 
class B
{
    public:
        B();
        virtual ~B();
        void bPrint(A aa);
    protected:
    private:
};
 
 
#endif // B_H

直接声明class A,而不是#include。

#include "B.h"
#include "A.h"
#include <iostream>
 
 
using namespace std;
B::B()
{
    //ctor
}
 
 
B::~B()
{
    //dtor
}
 
 
void B::bPrint(A aa)
{
    cout << "in B :" << aa.m_A << endl;
}

到B.cpp,必须#include "A.h",因为后面B::bPrint的实现需要完整的A的定音。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文