【问题标题】:“Undefined symbols” error in C++C++ 中的“未定义符号”错误
【发布时间】:2012-07-25 01:19:25
【问题描述】:

我昨天发布了这个。人们建议我应该拥有Point.hPoint.cpp 文件,因为我使用的是template。我为我的班级Point 创建了单独的文件,但我仍然收到错误。

//Point.h
Point(T = 0, T = 0, string = "Deafault Point");
~Point();
T operator-(const Point<T> &);  

//Point.cpp
template < typename T >
Point<T>::Point(T x,T y, string name)
:X(x), Y(y), Name(name)
{
}

template < typename T >
Point<T>::~Point()
{
}

template < typename T>
T Point<T>::operator-(const Point<T> &rhs)
{
cout << "\nThe distance between " << getName() << " and " 
<< rhs.getName() << " = ";

return sqrt(pow(rhs.getX() - getX(), 2) + pow(rhs.getY() - getY(), 2));;
}

//main.cpp
#include <iostream>
#include <math.h>
#include "Point.h"

using namespace std;

int main () {

Point<double> P1(3.0, 4.1, "Point 1");
cout << P1;

Point<double> P2(6.4, 2.9, "Point 2");
cout << P2;

cout << (P2 - P1);
return EXIT_SUCCESS;
}

这是我得到的:

Undefined symbols:
"std::basic_ostream<char, std::char_traits<char> >& operator<< <double (std::basic_ostream<char,  std::char_traits<char> >&, Point<double> const&)", referenced from:
  _main in main.o
  _main in main.o
"Point<double>::operator-(Point<double> const&)", referenced from:
  _main in main.o
"Point<double>::Point(double, double, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)", referenced from:
  _main in main.o
  _main in main.o
"Point<double>::~Point()", referenced from:
  _main in main.o
  _main in main.o
  _main in main.o
  _main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

感谢任何帮助...

【问题讨论】:

  • 您用于构建可执行文件的确切命令是什么?
  • 您发布的代码甚至都不是正确的。也许读过一本很好的 C++ 入门书?
  • 仅供参考,您的 operator- 不会强制返回类型 T。sqrt() 始终返回双精度。不一定是编译错误之一,但如果您执行Point&lt;int&gt;,您会感到头疼
  • @JackintheBox:现在更有意义了,不过请阅读sscce.org。如果我自己不能重现错误,真的很难提供解决方案。
  • @JackintheBox 因为您使用欧几里得度量来确定点之间的距离,所以我会强制它返回一个双精度值,即 double Point&lt;T&gt;::operator-(const Point&lt;T&gt; &amp;rhs) 我还想评论一下 pow(X, 2) 比 @ 慢987654333@,但我认为您不担心现阶段的表现:D

标签: c++ templates compiler-errors


【解决方案1】:

人们建议我应该有 Point.h 和 Point.cpp 文件,因为我使用的是模板

提出这个建议的人大错特错。模板的实现必须可见。

您可以将实现分离到一个文件中,但之后您也需要包含它。您可以隐藏模板的实现的唯一情况是您知道专业化并事先声明它们。 (此处不适用)

模板需要一个文件:

//Point.h

template <typename T>
struct Point
{
   Point(T = 0, T = 0, string = "Deafault Point");
   ~Point();
   T operator-(const Point<T> &);  
};

template < typename T >
Point<T>::Point(T x,T y, string name)
:X(x), Y(y), Name(name)
{
}

template < typename T >
Point<T>::~Point()
{
}

template < typename T>
T Point<T>::operator-(const Point<T> &rhs)
{
cout << "\nThe distance between " << getName() << " and " 
<< rhs.getName() << " = ";

return sqrt(pow(rhs.getX() - getX(), 2) + pow(rhs.getY() - getY(), 2));;
}

此外,标题中的 string 表明您在标题中也有一个 using namespace std;。这是不好的做法,删除 using 指令并限定名称 std::string

【讨论】:

    【解决方案2】:

    模板类的所有定义和实现的代码都应该写在'.h'文件中,否则会出现编译错误。

    【讨论】:

    • 不完全正确。实现需要可见,但不一定在.h 文件中。如果您事先了解所有专业,那就更不用说了。
    猜你喜欢
    • 2014-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-17
    • 2014-05-14
    • 2015-09-19
    相关资源
    最近更新 更多