如何消除程序中的链接器错误?

Posted

技术标签:

【中文标题】如何消除程序中的链接器错误?【英文标题】:How do I eliminate the linker errors in my program? 【发布时间】:2011-08-31 06:13:12 【问题描述】:

嗯,我正在为我的班级编写这段代码,但我在使用 Visual Studio 时遇到了链接器错误 LNK2019 和 LNK1120。我不太确定它为什么会这样做,但我离题了。

头文件:

        #ifndef PointClass   
        #define PointClass 
        #include <iostream>

namespace PointClass
              
     class point
      
        public:
        // CONSTRUCTOR
        point(double initial_x = 0.0, double initial_y = 0.0);
        // MODIFICATION MEMBER FUNCTIONS
        void shift(double x_amount, double y_amount);
        void rotate90( );
        // CONSTANT MEMBER FUNCTIONS
        double get_x( ) const  return x;  
        double get_y( ) const  return y; 
        // FRIEND FUNCTION
        friend std::istream& operator >>(std::istream& ins, point& target);
        double x, y; // x and y coordinates of this point
;

// NONMEMBER FUNCTIONS for the point class 
double distance(const point& p1, const point& p2);
point middle(const point& p1, const point& p2);
point operator +(const point& p1, const point& p2);
bool operator ==(const point& p1, const point& p2);
bool operator !=(const point& p1, const point& p2);
std::ostream& operator <<(std::ostream & outs, const point& source);
        

        #endif 

还有 CPP 文件:

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

        namespace PointClass
        
           point::point(double initial_x, double initial_y)
 
    x = initial_x;   // Constructor sets point to a given position
    y = initial_y;
 

void point::shift(double x_amount, double y_amount)
 
    x += x_amount;
    y += y_amount;   
 

void point::rotate90( )
 
    double new_x;
    double new_y;
    new_x = y;  // For a 90 degree clockwise rotation the new y is -1
    new_y = -x; // times original x, and the new x is the original y
    x = new_x;
    y = new_y;   
  

bool operator ==(const point& p1, const point& p2)
 
    return
        (p1.get_x( ) == p2.get_x( )) 
        &&
        (p1.get_y( ) == p2.get_y( ));
 

bool operator !=(const point& p1, const point& p2)
  
    return !(p1 == p2);
  

point operator +(const point& p1, const point& p2)
  
    double x_sum, y_sum;

    // Compute the x and y of the sum:
    x_sum = (p1.get_x( ) + p2.get_x( ));
    y_sum = (p1.get_y( ) + p2.get_y( ));
    point sum(x_sum, y_sum);
    return sum;
  

ostream& operator <<(ostream& outs, const point& source)
 
    outs << source.get_x( ) <<  " "  << source.get_y( );
    return outs;
 

istream& operator >>(istream& ins, point& target)

    ins >> target.x >> target.y;
    return ins;
 

int rotations_needed(point p)
  
    int answer;

    answer = 0;
    while ((p.get_x( ) < 0) || (p.get_y( ) < 0))
        
          p.rotate90( );
          ++answer;
        
    return answer;
  

void rotate_to_upper_right(point& p)
  
    while ((p.get_x( ) < 0) || (p.get_y( ) < 0))
      p.rotate90( );
  

double distance(const point& p1, const point& p2)

    double a, b, c_squared;

    // Calculate differences in x and y coordinates
    a = p1.get_x( ) - p2.get_x( ); // Difference in x coordinates
    b = p1.get_y( ) - p2.get_y( ); // Difference in y coordinates

    // Pythagorean Theorem to calculate square of distance between points
    c_squared = a*a + b*b;

    return sqrt(c_squared); // sqrt calculates square root
  

         point middle(const point& p1, const point& p2)

    double x_midpoint, y_midpoint;

    // Compute the x and y midpoints
    x_midpoint = (p1.get_x( ) + p2.get_x( )) / 2;
    y_midpoint = (p1.get_y( ) + p2.get_y( )) / 2;

    // Construct a new point and return it
    point midpoint(x_midpoint, y_midpoint);
    return midpoint;
         
        

有什么办法可以解决吗?

【问题讨论】:

复制和粘贴错误消息会更有建设性。 你用 -lm 选项编译..?? 我认为这会对你有所帮助***.com/questions/1252049/… 您在此处发布的代码并未指向链接器错误。您应该发布错误消息或整个程序。 @Steff 是的,你可以做很多事情来修复这个代码,或者至少让它变得更好。你得到的答案非常好,你应该阅读它们并确保你彻底理解它们。您可能应该倒带一点...删除一些函数并暂时注释您的代码,直到您对其进行编译和链接,然后从那里开始。关键是当你发现错误时,你要明白你的错误,这样你就不会重复它(或者至少记住如何修复它)。祝你好运! 【参考方案1】:

您似乎有一个名为 PointClass 的命名空间,并且标头保护使用 PointClass。考虑一开始就改变它。

#ifndef PointClass // Rename this, it might be ***ing with your namespace. 
#define PointClass
namespace PointClass

【讨论】:

+1 好点,虽然不是 OP 的问题。这将在using namespace PointClass 语句中产生编译器错误(因为'PointClass' 现在被''替换),但namespace PointClass PointClass::member... 语句很好。不过最好避免。 不,它会导致链接器错误。命名空间会变成一个未命名的命名空间,这意味着命名空间对于不同的编译单元会有所不同。这意味着永远不会为其他编译单元定义这些函数。 @Mankarse:它不会对我产生链接器错误(MSVC2008)。我怀疑他缺少其他一些实现。 @Martin。该代码本身不会导致链接器错误,但如果您尝试在不同的编译单元中使用该类,那么它会。我同意 Steff 可能还有其他问题。 @Mankarse:你是对的,使用来自另一个 cpp 单元的函数会导致链接错误(之前只有一个 .cpp)。我一直在使用更独特的守卫,所以从来没有想过他们就像任何其他宏一样:)【参考方案2】:

阅读错误信息:

Linker Error 2019: unresolved external symbol 'symbol' referenced in function 'function'

它为您提供了一个全局变量的名称,或者(更有可能)一个在没有定义的情况下调用的函数,即您没有为它编写函数体或没有将源代码及其定义添加到您的项目中。

错误 LNK1120 是第一个错误的结果。

如果没有完整的错误消息,就很难判断。正如@Darcy 指出的那样,您应该更改#ifdef#define 中的名称,因为

#define PointClass

告诉预处理器在下面的源代码中用 nothing 替换这个名称。这会导致 未命名 本地命名空间。此本地命名空间内定义的所有名称只能从该编译单元(cpp 文件)内访问。

为“包含守卫”选择一个唯一的名称,该名称不应出现在程序的其他任何地方。可能的模式可以模仿头文件的名称:

#define POINT_H

【讨论】:

以上是关于如何消除程序中的链接器错误?的主要内容,如果未能解决你的问题,请参考以下文章

使用函数指针消除 gcc 死代码

Qt-Creator 中 OpenCV 程序中的链接器错误

如何修复 xcode 中的 Apple Mach-O 链接器错误组问题?

如何解决 Firebase 中的 Apple Mach-O 链接器错误?

Visual Studio 2010 C++:如何判断链接器实际尝试链接的 LIB 文件?

如何修复 Xcode 中的“_sqlite3_prepare_v3”链接器错误