C++ 代码在 VS2019 上生成错误 LNK2005 和 LNK1169
C++ code generating errors LNK2005 & LNK1169 on VS2019
以下代码在 Visual Studio 2019 年生成错误 LNK2005 和 LNK1169。
LNK2005: "void__cdecl OverloadingPlus(void)" (?OverloadingPlus@@YAXXZ) already defined in main.obj
LNK1169: one or more multiply defined symbols found
我通过 Udemy 上的课程达到了这一点,讲师似乎没有问题。
类似的问题似乎与使用全局变量、在头文件中定义函数、不使用 #ifndef
守卫有关……但据我所知,情况似乎并非如此。
此问题仅在包含 operator+
重载后才开始出现,但 operator<<
不会触发任何错误,即使它们已以相同方式声明和定义。
有趣的是,如果我删除对 OverloadingPlus.h
文件的任何引用,并将 #include Complex.h
添加到 main.cpp,问题就会消失。
我看不出在 OverloadingPlus.h
中包含 Complex.h
如何专门对 operator+
的多重定义做出贡献,即使它在整个项目中只包含一次并且定义在 Complex.cpp
而不是在头文件中,正如类似问题的答案中所指出的那样。
还尝试用 #ifndef
语句包围 OverloadingPlus.h
的内容,只是为了确保它只使用一次而没有改变任何东西。
我试图在 class 中声明一个不同的 operator+
重载(你可以看到它被注释掉了),但它产生了同样的错误。
评论所有对任何其他文件的引用,以确保 Complex
定义仅包含一次。也没有帮助。
代码如下:
main.cpp
//#include "OverloadingAssignmentOperator.h"
//#include "OverloadingLeftBitShiftOperator.h"
//#include "ComplexNumberClass.h"
#include "OverloadingPlus.h"
int main() {
//OverloadingAssignmentOperator();
//OverloadingLeftBitShiftOperator();
//ComplexNumberClass();
OverloadingPlus();
return 0;
}
OverloadingPlus.h
#ifndef OVERLOADING_PLUS_H
#define OVERLOADING_PLUS_H
#include "Complex.hpp"
using namespace complex;
void OverloadingPlus() {
Complex c1(1, 4);
Complex c2(3, 2);
std::cout << c1 + c2 << std::endl;
}
#endif
Complex.hpp
#ifndef COMPLEX_HPP
#define COMPLEX_HPP
#include <iostream>
namespace complex {
class Complex {
private:
double real;
double imaginary;
public:
Complex();
Complex(double, double);
Complex(const Complex&);
const Complex& operator=(const Complex& other);
//const Complex operator+(const Complex& r);
double getReal() const { return real; }
double getImaginary() const { return imaginary; }
};
Complex operator+(const Complex& l, const Complex& r);
std::ostream& operator<<(std::ostream& out, const Complex& c);
}
#endif // !__COMPLEX_HPP__
Complex.cpp
#include "Complex.hpp"
namespace complex {
Complex::Complex() : real(0), imaginary(0) {}
Complex::Complex(double r, double i) : real(r), imaginary(i) {}
Complex::Complex(const Complex& other) {
std::cout << "Copy constructor..." << std::endl;
real = other.real;
imaginary = other.imaginary;
}
const Complex& Complex::operator=(const Complex& other) {
real = other.real;
imaginary = other.imaginary;
return *this;
}
//const Complex Complex::operator+(const Complex& r) {
// return Complex(real + r.getReal(), imaginary + r.getImaginary());
//}
//
Complex operator+(const Complex& l, const Complex& r) {
return Complex(l.getReal()+r.getReal(), l.getImaginary()+r.getImaginary());
}
std::ostream& operator<<(std::ostream& out, const Complex& c) {
out << "(" << c.getReal() << "," << c.getImaginary() << ")";
return out;
}
}
您忘记“内联”您的 OverloadingPlus
。
inline void OverloadingPlus() {
Complex c1(1, 4);
Complex c2(3, 2);
std::cout << c1 + c2 << std::endl;
}
应该可以消除链接器错误。
可能发生的情况是:您在多个编译单元中包含了“OverloadingPlus.h”(尽管您未能在问题中提供#include 的所有实例)。
每次在您的一个 .cpp 文件中包含“OverloadingPlus.h”时,您就添加了 void OverloadingPlus
的另一个定义到您的程序中。链接器检测到这一点,无法决定“正确的”,因此给出错误。
这个问题似乎与VS2019有关。将文件重命名为不同的名称,重建项目并将文件重命名回其原始名称解决了这个问题。
虽然按照其他人的建议使用 inline
确实规避了这个问题,但它并没有解决这个具体问题,因为冲突文件没有被多次包含。
以下代码在 Visual Studio 2019 年生成错误 LNK2005 和 LNK1169。
LNK2005: "void__cdecl OverloadingPlus(void)" (?OverloadingPlus@@YAXXZ) already defined in main.obj
LNK1169: one or more multiply defined symbols found
我通过 Udemy 上的课程达到了这一点,讲师似乎没有问题。
类似的问题似乎与使用全局变量、在头文件中定义函数、不使用 #ifndef
守卫有关……但据我所知,情况似乎并非如此。
此问题仅在包含 operator+
重载后才开始出现,但 operator<<
不会触发任何错误,即使它们已以相同方式声明和定义。
有趣的是,如果我删除对 OverloadingPlus.h
文件的任何引用,并将 #include Complex.h
添加到 main.cpp,问题就会消失。
我看不出在 OverloadingPlus.h
中包含 Complex.h
如何专门对 operator+
的多重定义做出贡献,即使它在整个项目中只包含一次并且定义在 Complex.cpp
而不是在头文件中,正如类似问题的答案中所指出的那样。
还尝试用 #ifndef
语句包围 OverloadingPlus.h
的内容,只是为了确保它只使用一次而没有改变任何东西。
我试图在 class 中声明一个不同的 operator+
重载(你可以看到它被注释掉了),但它产生了同样的错误。
评论所有对任何其他文件的引用,以确保 Complex
定义仅包含一次。也没有帮助。
代码如下:
main.cpp
//#include "OverloadingAssignmentOperator.h"
//#include "OverloadingLeftBitShiftOperator.h"
//#include "ComplexNumberClass.h"
#include "OverloadingPlus.h"
int main() {
//OverloadingAssignmentOperator();
//OverloadingLeftBitShiftOperator();
//ComplexNumberClass();
OverloadingPlus();
return 0;
}
OverloadingPlus.h
#ifndef OVERLOADING_PLUS_H
#define OVERLOADING_PLUS_H
#include "Complex.hpp"
using namespace complex;
void OverloadingPlus() {
Complex c1(1, 4);
Complex c2(3, 2);
std::cout << c1 + c2 << std::endl;
}
#endif
Complex.hpp
#ifndef COMPLEX_HPP
#define COMPLEX_HPP
#include <iostream>
namespace complex {
class Complex {
private:
double real;
double imaginary;
public:
Complex();
Complex(double, double);
Complex(const Complex&);
const Complex& operator=(const Complex& other);
//const Complex operator+(const Complex& r);
double getReal() const { return real; }
double getImaginary() const { return imaginary; }
};
Complex operator+(const Complex& l, const Complex& r);
std::ostream& operator<<(std::ostream& out, const Complex& c);
}
#endif // !__COMPLEX_HPP__
Complex.cpp
#include "Complex.hpp"
namespace complex {
Complex::Complex() : real(0), imaginary(0) {}
Complex::Complex(double r, double i) : real(r), imaginary(i) {}
Complex::Complex(const Complex& other) {
std::cout << "Copy constructor..." << std::endl;
real = other.real;
imaginary = other.imaginary;
}
const Complex& Complex::operator=(const Complex& other) {
real = other.real;
imaginary = other.imaginary;
return *this;
}
//const Complex Complex::operator+(const Complex& r) {
// return Complex(real + r.getReal(), imaginary + r.getImaginary());
//}
//
Complex operator+(const Complex& l, const Complex& r) {
return Complex(l.getReal()+r.getReal(), l.getImaginary()+r.getImaginary());
}
std::ostream& operator<<(std::ostream& out, const Complex& c) {
out << "(" << c.getReal() << "," << c.getImaginary() << ")";
return out;
}
}
您忘记“内联”您的 OverloadingPlus
。
inline void OverloadingPlus() {
Complex c1(1, 4);
Complex c2(3, 2);
std::cout << c1 + c2 << std::endl;
}
应该可以消除链接器错误。
可能发生的情况是:您在多个编译单元中包含了“OverloadingPlus.h”(尽管您未能在问题中提供#include 的所有实例)。
每次在您的一个 .cpp 文件中包含“OverloadingPlus.h”时,您就添加了 void OverloadingPlus
的另一个定义到您的程序中。链接器检测到这一点,无法决定“正确的”,因此给出错误。
这个问题似乎与VS2019有关。将文件重命名为不同的名称,重建项目并将文件重命名回其原始名称解决了这个问题。
虽然按照其他人的建议使用 inline
确实规避了这个问题,但它并没有解决这个具体问题,因为冲突文件没有被多次包含。