【问题标题】:Clion failed and got clang: error: linker command failed with exit code 1, but it work using clang++Clion 失败并收到 clang:错误:链接器命令失败,退出代码为 1,但它使用 clang++ 工作
【发布时间】:2021-05-21 10:47:34
【问题描述】:

我是 C++ 新手,现在我正在学习 Class。我正在使用“C++ 科学计算指南”一书并使用 Clion(用于 Mac)来编写我的代码并对其进行测试。昨天我遇到了一个奇怪的问题,我无法在 Clion 中运行我的代码,但它可以通过使用 clang++ file1 file2 file3 运行。

在 Clion 我得到了:

Undefined symbols for architecture x86_64:
  "ComplexNumber::ComplexNumber(double)", referenced from:
      _main in main.cpp.o
  "ComplexNumber::GetRealPart() const", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [2] Error 1
make[2]: *** [CMakeFiles/2.dir/all] Error 2
make[1]: *** [CMakeFiles/2.dir/rule] Error 2
make: *** [2] Error 2

这是我的头文件:

#ifndef COMPLEXNUMBERHEADERDEF
#define COMPLEXNUMBERHEADERDEF

#include <iostream>

class ComplexNumber
{
    private:
        double mRealPart;
        double mImaginaryPart;
    public:
        ComplexNumber();
        ComplexNumber(double x, double y);
        double CalculateModulus() const;
        double CalculateArgument() const;
        ComplexNumber CalculatePower(double n) const;
        ComplexNumber& operator=(const ComplexNumber& z);
        ComplexNumber operator-() const;
        ComplexNumber operator+(const ComplexNumber& z) const;
        ComplexNumber operator-(const ComplexNumber& z) const;
        friend std::ostream& operator<<(std::ostream& output,const ComplexNumber& z);

        double GetRealPart() const;
        double GetImaginaryPart() const;
        friend double RealPart(const ComplexNumber& z);
        friend double ImaginaryPart(const ComplexNumber& z);
        ComplexNumber(const ComplexNumber& z);
        ComplexNumber(double real);
        ComplexNumber CalculateConjugate() const;
        void SetConjugate();

        //not mandatory, but useful for exercise 6.1.7
        ComplexNumber operator*(const ComplexNumber& z) const;

};

因为到目前为止,我不需要使用所有函数,所以我只定义了我会使用的函数,例如:

#include "ComplexNumber.hpp"


ComplexNumber::ComplexNumber()
{
    mRealPart = 0.0;
    mImaginaryPart = 0.0;
}
// 6.1.1
double ComplexNumber::GetRealPart() const
{
    return mRealPart;
}

double ComplexNumber::GetImaginaryPart() const
{
    return mImaginaryPart;
}

// 6.1.2
double RealPart(const ComplexNumber& z)
{
    return z.GetRealPart();
}

double ImaginaryPart(const ComplexNumber& z)
{
    return z.GetImaginaryPart();
}

// 6.1.3
ComplexNumber::ComplexNumber(const ComplexNumber &z)
{
    mRealPart = z.mRealPart;
    mImaginaryPart = z.mImaginaryPart;
}

//6.1.4
ComplexNumber::ComplexNumber(double real)
{
    mRealPart = real;
    mImaginaryPart = 0.0;
}

ComplexNumber::ComplexNumber(double x, double y)
{
    mRealPart = x;
    mImaginaryPart = y;
}

//6.1.5
ComplexNumber ComplexNumber::CalculateConjugate () const
{
    double conjugate_real = mRealPart;
    double conjugate_imaginary = -mImaginaryPart;
    ComplexNumber conjugate(conjugate_real, conjugate_imaginary);
    return conjugate;
}

//6.1.6
void ComplexNumber::SetConjugate()
{
    double minus = -mImaginaryPart;
    mImaginaryPart = minus;
}

// overload operator =
ComplexNumber& ComplexNumber::operator=(const ComplexNumber &z)
{
    mRealPart = z.mRealPart;
    mImaginaryPart = z.mImaginaryPart;
    return *this;
}

// overload operator +
ComplexNumber ComplexNumber::operator+(const ComplexNumber &z) const
{
    ComplexNumber w;
    w.mRealPart = mRealPart + z.mRealPart;
    w.mImaginaryPart = mImaginaryPart + z.mImaginaryPart;
    return w;
}

// overload operator *
ComplexNumber ComplexNumber::operator*(const ComplexNumber &z) const
{
    ComplexNumber w;
    w.mRealPart = (mRealPart * z.mRealPart) - (mImaginaryPart * z.mImaginaryPart);
    w.mImaginaryPart = (mRealPart * z.mImaginaryPart) + (z.mRealPart * mImaginaryPart);
    return w;
}

在我的 main.cpp 中,我这样写来测试我的类:

#include "ComplexNumber.hpp"
#include <iostream>

using namespace std;

int main()
{
    ComplexNumber test(1.0);
    cout << test.GetRealPart() << endl;
    return 0;
}

对于 cmakelist,我是这样写的:

cmake_minimum_required(VERSION 3.19)
project(handin2)

set(CMAKE_CXX_STANDARD 14)

add_executable(1 ComplexNumber.cpp)
add_executable(2 main.cpp)
add_executable(4 test.cpp)

然后我得到了链接器错误,但它确实可以通过使用 clang++ main.cpp <.cpp>.

我该如何解决这个问题?

【问题讨论】:

    标签: cmake clang c++14 clion


    【解决方案1】:

    我认为您误解了 CMake。每个 add_executable 命令告诉 CMake 创建一个新的可执行文件,其中包含给定文件中的代码。所以你已经创建了三个可执行文件,每个都包含一个 .cpp 文件的代码。

    相当于你的命令行的 CMake 命令是:

    add_executable(executeable_name main.cpp <.cpp>)
    

    或者用具体的名字:

    add_executable(executeable_name main.cpp ComplexNumber.cpp)
    

    【讨论】:

    • 哦,是的!它现在对我有用。感谢您的提醒,并对这个幼稚的错误表示歉意:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多