简体   繁体   English

C ++如何知道使用Class.cpp文件?

[英]How does C++ know to use the Class.cpp file?

I have main.cpp , MyClass.cpp and MyClass.h files. 我有main.cppMyClass.cppMyClass.h文件。

main.cpp main.cpp

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

int main(){
    MyClass foo(123);
    std::cout << foo.getNumber();
}

MyClass.h MyClass.h

#ifndef MYCLASS_H
#define MYCLASS_H

class MyClass
{
    public:
        MyClass(int n);
        int getNumber();
    private:
        int fav_number;
};

#endif // MYCLASS_H

MyClass.cpp MyClass.cpp

#include "MyClass.h"

MyClass::MyClass(int n) {
    fav_number = n;
}

MyClass::getNumber(){
    return fav_number;
}

Now this program compiles and works fine as a project in CodeBlocks, but if I try to compile main seperately (not in a project) I get undefined reference to MyClass::MyClass(int) . 现在,该程序可以在CodeBlocks中作为项目进行编译并正常工作,但是,如果我尝试单独编译main(不在项目中),则会得到undefined reference to MyClass::MyClass(int) I think it is because in MyClass.h there is no body for the functions as they're in the cpp file. 我认为这是因为MyClass.h中没有函数的主体,因为它们位于cpp文件中。

So my question is: how does this program compile as a project even though MyClass.cpp isn't included anywhere in the main or the header? 所以我的问题是:即使MyClass.cpp不在主文件头或标头文件的任何位置,该程序如何作为项目编译?

When you add your cpp file to IDE it adds it to compile sources. 将cpp文件添加到IDE时,会将其添加到编译源。 Depends on your IDE, for example XCode has section compile sources: 取决于您的IDE,例如XCode具有部分编译源:

在此处输入图片说明

If you compile in console with g++, you need to type in console: 如果使用g ++在控制台中进行编译,则需要输入console:

g++ main.cpp MyClass.cpp

This means which source files to compile, after that linker should link their main.o MyClass.o files. 这意味着在该链接器链接后,应编译其源文件main.o MyClass.o文件。 IDE just do all this stuff by himself. IDE自己完成所有这些工作。

You compile each .cpp file independently (indeed, if you look at your compiler output, you should see main.o and MyClass.o ). 您可以独立地编译每个.cpp文件(实际上,如果查看编译器输出,则应该看到main.oMyClass.o )。 The header files simply tell the code that the definitions exist somewhere and after compiling, a linker is used to "link" the two .o files together. 头文件只是告诉代码定义在某处,并且在编译后,使用链接器将两个.o文件“链接”在一起。 It is during the linking stage that the definitions are resolved, so when main.o refers to code in MyClass.o , the linker is what puts these together. 正是在链接阶段解决了这些定义,因此,当main.o引用MyClass.o代码时,链接器将这些内容组合在一起。

CodeBlocks hides this from you, but its calling out to your compiler and linker to do this. CodeBlocks对您隐藏了此内容,但它会调用您的编译器和链接器来执行此操作。 (Actually, if you call gcc with all of your .cpp files, it will call the linker for you too, but this is simply a convenience and you can do it in multiple steps too. If you are using gcc to compile, your linker is usually ld ) (实际上,如果您使用所有.cpp文件调用gcc ,它也会为您调用链接器,但这只是一种方便,您也可以分多个步骤进行操作。如果使用gcc进行编译,则链接器通常是ld

You tell it to. 你告诉它。

When using an IDE, the list of files in the "project" determines what list of filenames the IDE sends to the compiler, in a build command . 使用IDE时,“项目”中的文件列表决定了IDE在build命令中发送给编译器的文件名列表。

When invoking the build command manually, you have to do that yourself. 手动调用build命令时,您必须自己执行此操作。

For example: 例如:

g++ -o myprogram main.cpp MyClass.cpp

Or: 要么:

g++ -c main.cpp
g++ -c MyClass.cpp
g++ -o myprogram main.o MyClass.o

Obviously add other flags as needed (include paths etc). 显然,根据需要添加其他标志(包括路径等)。

On MyClass.cpp you've forgotten return type specified on its header MyClass.h as follows MyClass.cpp上,您忘记了在其标头MyClass.h上指定的返回类型,如下所示

int MyClass::getNumber(){
    return fav_number;
}

From a terminal console you must pass to the compiler g++ as argument all the files *.cpp which main depends on otherwise you will have an error as follows: 从终端控制台,您必须将主要依赖的所有文件* .cpp作为参数传递给编译器g ++,否则将出现以下错误:

$ g++ main.cpp
/tmp/ccDTbMs5.o: In function `main':
main.cpp:(.text+0x15): undefined reference to `MyClass::MyClass(int)'
main.cpp:(.text+0x21): undefined reference to `MyClass::getNumber()'
collect2: error: ld returned 1 exit status

As you can see the compiler is trying to look for object code that is not found. 如您所见,编译器正在尝试查找未找到的目标代码。 When you compile main.cpp along with all the cpp files corresponding to the includes on your main. 当您编译main.cpp以及与main上的include对应的所有cpp文件时。 In this manner it will work for you as follows: 通过这种方式,它将为您提供以下服务:

$ g++ main.cpp MyClass.cpp -o myprogram
$ 
$ ./myprogram 
123

Option -o change the output program to "myprogram". 选项-o将输出程序更改为“ myprogram”。

More complex situations can be treat using builders such as "Makefile". 可以使用“ Makefile”之类的构建器来处理更复杂的情况。

In case you do not have the implementation files .cpp for each of your header files .h , you should have instead the binary object code. 如果没有每个头文件.h的实现文件.cpp,则应使用二进制目标代码。 This should be passed to the g++ accordanly. 这应该相应地传递给g ++。

$ g++ -c MyClass.cpp
$ g++ -c main.cpp

The previous lines creates MyClass.o and main.o. 前几行创建MyClass.o和main.o。 Notice that the -c is passed to the compiler to indicate that only compilation will be done. 请注意,-c传递给编译器以指示仅将完成编译。 Now you can pass the objects to the compiler as follows linking all of then together: 现在,您可以将对象传递给编译器,如下所示,将所有这些对象链接在一起:

$ g++ -o prog MyClass.o main.o
$ ./prog 
123 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM