C ++友元函数不起作用(具有多个头文件和源文件)

时间:2018-01-17 13:45:00

标签: c++

我试图在互联网上找到一个解决方案,但我总是找到一些例子,其中类,主要功能等都写在一个文件中,而不是分开。也许这就足够了,但我是C ++的新手,我想我的问题不同了,因为我为每个类使用不同的头文件和源文件,为main()使用不同的源文件。
所以,问题是:我试图在Box2类中使printBoxMeretek(Box)函数成为Box类的友元函数。它没有用,我也不知道为什么。当我把整个Box2类作为Box类的朋友时,一切都还可以。我该怎么办,如果我只想将printBoxMeretek(Box)函数作为朋友,而不是整个Box2类?
无论如何,错误信息表明问题是Box类中的boxSzelesseg和boxMagassag变量是私有的。但据我所知,朋友函数应该能够处理私有变量。
以下是我的测试文件的内容:
Box.h

#ifndef BOX_H
#define BOX_H

class Box
{
    //friend function from Box2 [can be written anywhere: in private, in public,etc section] =>It does NOT work...why???
    friend void printBoxMeretek(Box);

    //make the whole Box2 class friend =>It works well.
//    friend class Box2;

    public:
};

#endif // BOX_H


Box2.h

#ifndef BOX2_H
#define BOX2_H

#include <iostream>
#include <Box.h>

class Box2
{
    public:
        void printBoxMeretek(Box)
        { }
};

#endif // BOX2_H


感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

friend void printBoxMeretek(Box);

这声明 free 函数是Box的朋友。您希望成员函数成为朋友,因此您应该声明:

class Box2;
class Box
{
    friend void Box2::printBoxMeretek(Box);
};

现在问题是,你需要完整的类声明,所以:

class Box;
class Box2;
{
public:
    void printBoxMeretek(Box);
};

class Box
{
    friend void Box2::printBoxMeretek(Box);
};

如果你在同一个标​​题中或在其中两个标题中有这个并不重要 - 问题仍然存在(即你需要在Box.h中包含Box2.h)。

附注(感谢Martin,澄清):尽管使用Box类声明了一个函数,但只有在 define 时才能使用该类的完整定义。或者调用函数,所以这样可以正常工作。你必须确保在你做其中一个的地方包括两个标题(或者总是包含Box.h,它随后是Box2.h)。

但您可能更喜欢参考。您的盒子类看起来并不像我真的打算在每次调用print函数时复制它们一样:

void Box2::printBoxMeretek(Box const& b);

答案 1 :(得分:2)

   //friend function from Box2 [...]
   friend void printBoxMeretek(Box);

因为来自Box2的功能。相反,它是全局命名空间::printBoxMeretek中的独立函数的声明。

而你需要的是:

    friend void Box2::printBoxMeretek(Box);

...但要做到这一点,您需要先定义Box2 - 所以#include "Box2.h"位于Box.h的顶部。

最后的皱纹,就是Box2.h不能包含Box.h(否则你有一个循环包含)。幸运的是你不需要。而不是#include "Box.h",只需使用声明该类的class Box;(因此可以将其用作函数参数),但不定义它(因此您不能创建类型为{{1的变量) }})。

所以,Box2.h:

Box

请注意,我已经省略了警卫。你想要那些。

Box.h:

class Box;

class Box2 { 
public:
    void PrintBox(Box b); 
};

Box.cpp

#include "Box2.h"
class Box {
    int v;
public:
    Box(int v);
    friend void Box2::PrintBox(Box b);

};

Box2.cpp

#include "Box.h"
Box::Box(int v) : v(v) {}

的main.cpp

#include "Box2.h" // Always put "our" header first to check it includes everything.
#include "Box"    // Needed to define member function
#include <iostream>

Box2::PrintBox(Box b) {
    std::cout << b.v << std::endl;
}