【问题标题】:why can't the compiler find the method definitions in .cpp file为什么编译器在 .cpp 文件中找不到方法定义
【发布时间】:2016-06-10 14:44:16
【问题描述】:

我有一个用于声明类的头文件、一个用于定义其方法的 cpp 文件和一个主源文件,我主要包含了头文件,但编译器抱怨我没有定义他的方法。 .. 日期.h

    #ifndef _DATE_
#define _DATE_
#include <iostream>
#include <exception>
#include <string>

using namespace std;
class date{
    int day, month, year;
public:
    date(int d, int m, int y) :day(d), month(m), year(y){}
    int getDay() const{ return day; }
    int getMonth() const { return month; }
    int getYear() const { return year; }
    bool operator==(const date& d) const{ return ((day == d.day) && (month == d.month) && (year == d.year)); }
    bool operator>(const date& d) const;
    bool operator<(const date& d) const { return !(*this>d || *this == d); }
    ostream& print(ostream& os) const;
};


#endif

日期.cpp

#include "Date.h"

bool date::operator>(const date& d) const {
    if (year > d.year)  return true;
    if (year < d.year)  return false;
    if (month>d.month)  return true;
    if (month < d.month)    return false;
    if (day>d.day)  return true;
    return false;
}

ostream& date::print(ostream& out) const    {
    if (day < 10)   out << "0";
    out << day << "/";
    if (month < 10) out << "0";
    out << month << "/";
    out << year << endl;
    return out;
}



ostream& operator<<(ostream& ot, const date& d) {
    return d.print(ot);
}

main.cpp

#include "Date.h"

int main()  {
    date d(17, 10, 1996);
    cout << d;
    return 0;
}

错误: 错误 1 ​​错误 C2679:二进制“

2   IntelliSense: no operator "<<" matches these operands
        operand types are: std::ostream << date c:\Users\aub\Documents\Visual Studio 2013\Projects\Project22\Project22\main.cpp 5

我也尝试在 date.h 中实现我的重载运算符

在头文件中声明 operator & __cdecl operator &,class date const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std @@@std@@AAV01@ABVdate@@@Z) 已经定义在 Date.obj c:\Users\aub\documents\visual studio 2013\Projects\Project22\Project22\main.obj

错误 2 错误 LNK1169:找到一个或多个多重定义符号 c:\users\aub\documents\visual studio 2013\Projects\Project22\Debug\Project22.exe 1

【问题讨论】:

  • 编译器不会在其他 cpp 文件中查找声明。 operator&lt;&lt; 没有像其他文件一样在标头中声明并在实现文件中定义,是什么让operator&lt;&lt; 如此特别?
  • “我也尝试在 date.h 中实现我的重载运算符
  • [OT]:我会将return !(*this&gt;d || *this == d); 替换为return d &gt; *this;
  • 我认为这不能解决我的问题...
  • [OT]:避免using namespace std;,尤其是在标题中。

标签: c++ header include operator-overloading


【解决方案1】:

ostream&amp; operator&lt;&lt;(ostream&amp; ot, const date&amp; d); 的声明应该在标题中。

【讨论】:

  • 声明,而不是定义(或内联定义)。
【解决方案2】:

当您编译 .cpp 文件时,编译器只会看到您直接或间接包含的文件和头文件。如果您有一个来自一个 .cpp 文件的函数从另一个文件调用另一个函数 - 由称为链接器的不同程序解析。因此,在此之前,您必须让编译器知道这样的函数存在于某处。在您编译main.cpp 的情况下,没有关于class dateoperator&lt;&lt; 的信息,因此您需要在某处声明它以使其在编译main.cpp 时对编译器可见:

ostream& operator<<(ostream& ot, const date& d); //declaration, tells compiler such function exists somewhere

最好的地方是标题。

现在,如果您尝试将此函数定义而不是该声明放在标题中,您将遇到另一个问题 - 两个 .cpp 文件都会看到它并且函数将被定义两次,这是一个错误。您可以避免标记该函数inline 出现问题,然后在每个编译单元中多次定义它就可以了。所以要么你需要在header中声明并只在一个cpp文件中定义,或者你可以在header中内联定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    相关资源
    最近更新 更多