Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
函数有多个定义时出错 几年前我尝试重新学习C++,我遇到了一些基本问题。我当前的问题发生在尝试使用friend函数时。这是我在2个文件中的代码_C++_Definition_Friend - Fatal编程技术网

函数有多个定义时出错 几年前我尝试重新学习C++,我遇到了一些基本问题。我当前的问题发生在尝试使用friend函数时。这是我在2个文件中的代码

函数有多个定义时出错 几年前我尝试重新学习C++,我遇到了一些基本问题。我当前的问题发生在尝试使用friend函数时。这是我在2个文件中的代码,c++,definition,friend,C++,Definition,Friend,第一: // fun.cpp #include <iostream> using namespace std; class classA { friend void funct(); public: classA(int a=1,int b=2):propa(a),propb(b){cout<<"constructor\n";} private: int propa; int propb; void outfun(){

第一:

// fun.cpp

#include <iostream>
using namespace std;

class classA {
    friend void funct();
public:
    classA(int a=1,int b=2):propa(a),propb(b){cout<<"constructor\n";}
private:
    int propa;
    int propb;
    void outfun(){
        cout<<"propa="<<propa<<endl<<"propb="<<propb<<endl;
    }
};
void funct(){                     // ERROR HERE
    cout<<"enter funct"<<endl;
    classA tmp(1,2);
    tmp.outfun();
    cout<<"exit funct"<<endl;
}
//fun.cpp
#包括
使用名称空间std;
甲级{
friend-void函数();
公众:

classA(inta=1,intb=2):propa(a),propb(b){cout问题是,如果在程序中的两个位置包含fun.cpp,那么最终将定义它两次,这是无效的

您不想包括
cpp
文件。您想包括头文件

头文件应该只有类定义。您将单独编译的相应
cpp
文件将有函数定义

fun.hpp:

#include <iostream>

class classA {
    friend void funct();
public:
    classA(int a=1,int b=2):propa(a),propb(b){std::cout<<"constructor\n";}
private:
    int propa;
    int propb;
    void outfun(){
        std::cout<<"propa="<<propa<<endl<<"propb="<<propb<< std::endl;
    }
};
#包括
甲级{
friend-void函数();
公众:

CyrA(int A=1,int B=2):PROPA(A),PROB(B){STD::CUT

这里是一个高度简化但希望相关的视图,当您在C++中构建代码时发生了什么。 C++将生成机器可执行代码的负载分为以下不同阶段-

  • 预处理-这是您可能正在使用的任何宏
  • #定义
    s等的扩展位置

  • 编译-每个cpp文件以及该文件中直接或间接(统称为编译单元)的所有
    #include
    d文件被转换为机器可读的目标代码

    <>这是C++还检查所有函数定义的(即包含在代码< > {<代码/代码>代码> } /代码>的正文。
    void Foo(int x){return Boo(x);})
    正在以有效的方式引用其他函数

    这样做的方式是,在调用它之前,坚持至少提供这些其他函数的声明(例如,
    void Boo(int);
    ),以便它可以检查您是否正确调用了它。这可以直接在调用它的cpp文件中完成,也可以通常在包含的头文件中完成

    请注意,只有与此cpp中定义的函数和包含的文件相对应的机器代码才会构建为此编译单元的对象(二进制)版本(例如Foo),而不是仅声明的机器代码(例如Boo)

  • >强>链接< /强> -这是C++在每个编译单元中声明和调用的对象进行搜索的阶段,并将其链接到调用它的地方。现在如果没有找到该函数的定义,链接器就会放弃和错误。(本质上是它所使用的名称和参数类型)它也会出错,因为它认为它是不明确的,并且不想随意选择一个

    后者就是您的情况。通过对
    fun.cpp
    文件执行
    #include
    fun.cpp
    main.cpp
    都有
    funct()
    的定义,链接器不知道在您的程序中使用哪一个,并且正在抱怨


    Vaughn提到的修复方法是在
    mainfile.cpp
    中不包含定义为
    funct()
    的cpp文件,而是将
    funct()
    的声明移动到单独的头文件中,并将其包含在
    mainline.cpp
    中。这样编译器将获得
    funct()的声明<代码> >链接器将得到一个定义:<代码>函数()/>代码> <代码>乐趣.CPP < /代码>,并将它带到信心。

    < p>这个问题发生是因为您调用了“代码>乐趣.CPP < /C>”而不是<代码>乐趣.HPP。因此C++编译器发现函数.CPP定义两次,并引发此错误。 将
    main.cpp
    文件的第3行从
    #包含“fun.cpp”
    更改为
    #包含“fun.hpp”
    您有
    #包含“fun.cpp”
    main文件.cpp
    中,因此编译时使用:

    g++-o hw1 mainfile.cpp
    
    但是,如果将这些链接在一起进行编译,则

    g++-g-std=c++11-Wall-pedantic-c-o-fun.o-fun.cpp
    g++-g-std=c++11-Wall-pedantic-c-o mainfile.o mainfile.cpp
    
    正如上面提到的,添加
    #包括“fun.hpp”
    将需要完成,否则将无法工作。但是,您使用
    func()
    函数的情况与我的问题略有不同


    我在执行HW分配和由较低的bash配方编译的自动加载器时遇到了这个问题,但在本地,它使用较高的bash工作。

    它还可以帮助一些链接器包装标题保护——继续搜索#ifndef@CarlNorum我的印象是,多个定义错误是链接器错误,而不是编译错误。但也许我是错了。是的,但标题保护与此无关。除非你在标题中做了一些疯狂的事情,那就是。为什么它适用于类而不是函数?我看不出与要求将其放置在cpp文件中的类定义相比,函数有什么特殊之处。@ElefEnt:类纯粹是编译时的实体。如果定义了一个从未使用过的类,则编译器不会创建任何机器代码。但是,非内联函数定义意味着实际创建机器代码,无论您是否使用它。您只希望该机器代码存储在一个对象文件中。如果要将函数定义放在头中,则d意味着在包含标题的任何位置创建机器代码。
    #include <iostream>
    
    class classA {
        friend void funct();
    public:
        classA(int a=1,int b=2):propa(a),propb(b){std::cout<<"constructor\n";}
    private:
        int propa;
        int propb;
        void outfun(){
            std::cout<<"propa="<<propa<<endl<<"propb="<<propb<< std::endl;
        }
    };
    
    #include "fun.hpp"
    
    using namespace std;
    
    void funct(){
        cout<<"enter funct"<<endl;
        classA tmp(1,2);
        tmp.outfun();
        cout<<"exit funct"<<endl;
    }
    
    #include <iostream>
    #include "fun.hpp"
    using namespace std;
    
    int main(int nargin,char* varargin[]) {
        cout<<"call funct"<<endl;
        funct();
        cout<<"exit main"<<endl;
        return 0;
    }