C++ 中的多个类定义错误,我的头文件有问题吗?

Posted

技术标签:

【中文标题】C++ 中的多个类定义错误,我的头文件有问题吗?【英文标题】:Multiple class definition error in C++, is something wrong with my header files? 【发布时间】:2018-11-18 01:27:05 【问题描述】:

我只在 .hpp 文件中声明该类一次,并在另一个 .cpp 文件中实现其成员函数。按该顺序排列的 .cpp 和 .hpp 文件如下所示。我在 .cpp 文件中得到错误。第一个是在第 6 行,说“complex::complex 的多重定义”和“这里首先定义”这发生在每个函数上,包括重载的 ctor。当我尝试将它们的原型包含在 .hpp 文件中时,我是否无意中定义了所有这些函数?

只要我在使用该类的主文件中包含 .hpp 文件而不是 .cpp,我就不会收到任何错误。这有什么意义?编译器如何访问包含所有函数定义的 .cpp 文件?

#include <iomanip>      // For fixed, setprecision()
#include <sstream>      // For stringstream class
#include "Complex.hpp"  // For the complex class declaration


    complex::complex()
    
        init(0,0);
    
 
 complex::complex(double init_real, double init_imag)
 
    init(init_real, init_imag);
 


 double complex::get_imag()
 
     return m_imag;
 


    double complex::get_real()
    
        return m_real;
    


//--------------------------------------------------------------------------------------------------
void complex::init(double init_real, double init_imag)
    
        m_real = init_real;
        m_imag = init_imag;
    

void complex::set_imag(double s)
    
        m_imag = s;
    
-
void complex::set_real(double s)
    
        m_real = s;
    


std::string complex::to_string()

    std::stringstream sout;
    sout << std::fixed << std::setprecision(4);
    sout << "(" << get_real();
    double imag = get_imag();
    if (imag < 0) 
        sout << " - " << -imag << 'i';
     else if (imag > 0) 
        sout << " + " << imag << 'i';
    
    sout << ")";
    return sout.str();

#ifndef COMPLEX_HPP  // See the comments in the header comment block regarding these two lines.
#define COMPLEX_HPP

#include <string> // Included because we are using the string class in to_string()
class complex

    public:

    complex();

    complex(double , double);

    double get_imag();

    double get_real();

    void set_imag(double);

    void set_real(double);

    std::string to_string();

    private:

    void init(double , double );

    double m_real;

    double m_imag;
;

#endif

使用这些的主文件:

#include <fstream> // For ofstream class declaration
#include <iostream> // For cout, endl
#include "Complex.hpp" // So we can access the complex class declaration (hint: see Complex.cpp)
#include <string>


int main()

    std::string filename; filename = "complex-test.txt";
    std::ofstream...
    .
    .
    .
    return 0;

【问题讨论】:

Complex.hpp 似乎在 前面缺少class complex main 的编译器只需要函数/类声明 (.hpp),而不是实现/定义。链接器找到那些。 #includeing .cpp 文件可以完成,但非常奇怪。 @zzxyz 链接器如何找到它们? .hpp 中没有任何内容可以将其连接到具有类实现的 .cpp 文件?另外,我忘记在此处粘贴“类复杂”部分,现在应该可以了 编译器会编译你的主文件和其他 cpp 文件。 LINKER 将它们组合在一起以制作您的 exe。 @Tyler 这实际上是由于名称修改和链接时间优化等原因而定义的实现。简短的回答是链接器查看目标文件并构建符号表,如果找不到任何符号,您将收到错误。 【参考方案1】:

包含一个 cpp 文件相当于在该文件中导入定义。这意味着您在实际定义的 cpp 文件中有一个定义,并且该定义静默地进入您包含的文件中。这样,链接器会为同一函数生成 2 个定义副本并感到困惑。 编译应该没问题,但链接会导致问题。尝试避免 #include 中的 cpp 文件

【讨论】:

以上是关于C++ 中的多个类定义错误,我的头文件有问题吗?的主要内容,如果未能解决你的问题,请参考以下文章

c++头文件相互包含

在 C++ 中将我的类分成不同的头文件

C++ 中的多个定义 (Visual Basic 2010)

在 C++ 中的类构造函数中初始化结构数组

在源文件中定义静态方法,并在 C++ 中的头文件中声明

C++ 中的头文件和命名空间