c++ - 如何在与主函数不同的源文件中定义我的类?

标签 c++

虽然应该很简单,但我只是不知道如何将源代码分成不同的文件。

当我的代码被编写为单个源文件时,它可以很好地编译和执行:

#include <iostream>
using namespace std;

class Greeter{ 
    public:
        void greet();
};

void Greeter::greet(){
    cout << "Hello World!";
}

int main(){
    Greeter greeter;
    greeter.greet();
    return 0;
}

但尽我所能,将代码分成单独的源文件:

Greeter.h

#include <iostream>
using namespace std;

class Greeter{ 
    public:
        Greeter();
        void greet();
};

Greeter.cxx

#include <iostream>
#include "Greeter.h"
using namespace std;

void Greeter::greet(){
    cout << "Hello World!";
}

main.cxx

#include <iostream>
#include "Greeter.h"
using namespace std;

int main(){
    Greeter greeter;
    greeter.greet();
    return 0;
}

总是导致编译错误:

main.cxx:(.text+0x16): undefined reference to `Greeter::Greeter()'

最佳答案

目前尚不清楚这些评论是否解决了您的问题。在将源分为 header 和多个源时,错误证明的主要问题是您为 class Greeter 包含了不完整的构造函数。在Greeter.h 。具体来说,您无法包含“空参数列表”来完成构造函数,例如

    Greeter() {};   /* default construct */

参见cppreference - Default constructors

您应该避免的下一个问题是包含 using namespace std;在头文件中。请参阅“using namespace” in c++ headers 。相反,只需调用cout即可, std::cout并消除了完全包含命名空间的需要。

接下来,同时 iostream具有适当的 header 防护,您只需将其包含在 Greeter.cpp 中(这是使用 iostream 函数的唯一来源)。您还应该在 Greeter.h 中包含 header 防护装置。以防止编译期间出现多重包含。只需创建一个 #define并检查 header 中是否已定义,例如

greeter.h

#ifndef my_class_greeter_h
#define my_class_greeter_h  1

class Greeter { 

    public:
        Greeter() {};   /* default construct */
        void greet();
};

#endif

现在每个包含 greeter.h 的文件如果 my_class_greeter_h 将避免再次包含它已经定义了。

greeter.cpp

包含类函数定义的源文件是依赖 iostream 的唯一源。调用,并且是唯一需要 #include <iostream> 的文件,例如

#include <iostream>

#include "greeter.h"

void Greeter::greet(){
    std::cout << "Hello World!\n";
}

ma​​in.cpp

main.cpp源文件只需包含包含类定义的 header ,例如

#include "greeter.h"

int main (void) {

    Greeter greeter;    /* instantiate greeter */
    greeter.greet();    /* call greet() */

    return 0;
}

两个源都必须编译

编译单独的源文件需要main.cppgreeter.cpp进行编译(将 greeter.cpp 编译为对象,或者简单地将 .cpp 文件包含在编译字符串中)。

使用 gcc/clang 进行编译

$ g++ -Wall -Wextra -pedantic -std=c++11 -Ofast -o main main.cpp greeter.cpp

使用 VS 编译 ( cl.exe )

> cl /nologo /W3 /Ox /EHsc /Femain /TP main.cpp greeter.cpp

(在没有警告的情况下编译之前不接受代码)

示例使用/输出

无论哪种情况,输出都符合预期:

$ ./main
Hello World!

仔细检查一下,如果您还有其他问题,请告诉我。

关于c++ - 如何在与主函数不同的源文件中定义我的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54339115/

相关文章:

c++ - 链接具有不兼容依赖项的库

c++ - 为什么本地类中不允许使用静态数据成员?

c++ - CMake 不编译 OpenCV

c++ - 简单的变换 tolower 不起作用

c++ - 为什么 C++11 中没有 `static_if`

c++ - 如何实现 vector::clear()? (学习目的)

c++ - C++14 和 C++17 之间的默认构造函数调用区别

c++ - 是否可以将一个视频帧投影到另一个图像中?

c++ - 使用 Qt 更新/渲染游戏对象

c++ - 二进制补码函数的问题