2016-06-10 2 views
0

У меня есть заголовочный файл для объявления класса, файла cpp для определения его методов и основного исходного файла, в основном я включил заголовочный файл , но компилятор жалуется, что я не определил его методы ... Date.hПочему компилятор не находит определения методов в файле .cpp

#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 

Date.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: двоичный '< <': оператор не найден, который принимает правый операнд типа 'date' (или нет приемлемого преобразования) c: \ users \ aub \ documents \ visual студии 2013 \ проекты \ project22 \ project22 \ main.cpp 5

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, но вместо этого не получилось ...

ошибки, которые я получаю после объявления оператора < < в файле заголовка, а именно:Ошибка 1 ошибка LNK2005:? "Класс станд :: basic_ostream> & __cdecl оператор < < (класс станд :: basic_ostream> &, дата класса 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

+0

Компилятор не ищет в других файлах cpp для деклараций. Что делает 'operator <<' особенным, что он не объявлен в заголовке и не определен в файле реализации, как другие? – chris

+0

«Я также попытался реализовать мой перегруженный оператор << в date.h вместо этого, но не работал ...» Какое сообщение об ошибке для него? – songyuanyao

+0

[OT]: Я бы заменил 'return!(* this> d || * this == d); 'by' return d> * this; '. – Jarod42

ответ

1

Объявление ostream& operator<<(ostream& ot, const date& d); должно быть в заголовке.

+0

У меня были еще худшие ошибки .... – stringson

+0

** Декларация **, а не ** определение ** (или ** встроенное ** определение). – Jarod42

0

Когда вы компилируете компилятор .cpp, он видит только тот файл и заголовки, которые вы прямо или косвенно включаете. Если у вас есть одна функция из одного .cpp-файла, вызывающего другой файл из другого файла, который разрешен другой программой, называемой компоновщиком. Поэтому, прежде чем это произойдет, вы должны сообщить компилятору, что такая функция существует где-то. В вашем случае при компиляции main.cpp нет никакой информации о operator<< для class date, так что вы должны объявить его где-нибудь, чтобы сделать его видимым для компилятора при компиляции main.cpp:

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

и лучшее место для этого является заголовок.

Теперь, если вы попытаетесь поместить это определение функции, а не объявление в заголовок, вы получите другую проблему - оба .cpp-файла увидят его, и функция будет определена дважды, что является ошибкой. Вы можете избежать проблем с маркировкой этой функции inline, и тогда это прекрасно, чтобы определить ее несколько раз в каждом блоке компиляции. Поэтому либо вам нужно объявить его в заголовке, либо определить только в одном файле cpp, либо вы можете определить его в строке в заголовке.

+0

Я сделал это, и теперь он работает, спасибо! – stringson

Смежные вопросы