Неопределенная ссылка на оператор ››

Я пытаюсь работать над перегрузкой оператора, мой заголовочный файл состоит из:

#ifndef PHONENUMBER_H
#define PHONENUMBER_H

#include<iostream>
#include<string>
using namespace std;

class Phonenumber
{
    friend ostream &operator << ( ostream&, const Phonenumber & );
    friend istream &operator >> ( istream&, Phonenumber & );
private:
    string areaCode;
    string exchange;
    string line;

};

#endif // PHONENUMBER_H

И определение класса

//overload stream insertion and extraction operators
//for class Phonenumber
#include <iomanip>
#include "Phonenumber.h"
using namespace std;
//overloades stram insertion operator cannot be a member function
// if we would like to invoke it with
//cout<<somePhonenumber
ostream &operator << ( ostream &output, const Phonenumber &number)
{

    output<<"("<<number.areaCode<<")"
     <<number.exchange<<"-"<<number.line;
    return output;

}//end function opertaor <<

istream &operator >> ( istream &input, Phonenumber &number)
{
    input.ignore(); //skip (
    input>>setw(3)>>number.areaCode;//input areacode
    input.ignore(2);//skip ) and space
    input>>setw(3)>>number.exchange;//input exchange
    input.ignore();//skip -
    input>>setw(4)>>number.line;//input line
    return input;
}

вызов через main

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

int main()
{
    Phonenumber phone;
    cout<<"Enter number in the form (123) 456-7890:"<<endl;
    //cin>> phone invokes operator >> by implicitly issuing the non-member function call operator>>(cin,phone)
    cin >> phone;
    //cout<< phone invokes operator << by implicitly issuing the non-member function call operator>>(cout,phone)
    cout << phone<<endl;
    return 0;
}

но компиляция этого показывает мне ошибку компилятора: undefined reference to 'operator>>(std:istream&, Phonenumber&)' Может ли кто-нибудь помочь мне решить эту ошибку


person Avinash Gopal    schedule 22.06.2012    source источник
comment
Я вижу istraem в определении оператора входного потока. Но это просто опечатка, не так ли?   -  person Luca Geretti    schedule 22.06.2012
comment
Разве вы не определяете левостороннего оператора? Разве он не вызовет этот оператор, только если вы напишете phonenumberObj << ostrObj? Редактировать: Неважно, как-то пропустили второй аргумент ^^   -  person Sebastian Hoffmann    schedule 22.06.2012
comment
Некоторые люди скажут вам никогда не использовать using namespace std;. Я бы не стал заходить так далеко, я думаю, все в порядке, пока вы ограничиваете его возможности. Но я думаю, что все согласятся с тем, что вы не должны помещать его в глобальное пространство имен в заголовке.   -  person Benjamin Lindley    schedule 22.06.2012
comment
@BenjaminLindles Кто это сказал? Я согласен с вами, что использовать его в глобальном пространстве (например, в заголовке) плохо. Но почему кого-то должно волновать, используете ли вы его в своих файлах реализации? Это делает код намного более читаемым, и обычно вы не будете создавать с ним двусмысленные имена. Если вы это сделаете, просто используйте эти несколько классов явно с пространством имен.   -  person Sebastian Hoffmann    schedule 22.06.2012
comment
@Paranaix: Задайте несколько вопросов в более загруженное время дня с using namespace std; в них, и вы узнаете, кто это говорит. Не я.   -  person Benjamin Lindley    schedule 22.06.2012
comment
вам действительно следует удалить этот using namespace std; из Phonenumber.h.   -  person moooeeeep    schedule 22.06.2012
comment
Не используйте using namespace std;. Это бесполезно для начинающих; это бесполезно в больших проектах; он имеет очень ограниченное законное использование. stackoverflow.com/search?q=using+namespace+std+[c%2B%2B ]   -  person CB Bailey    schedule 22.06.2012
comment
сам код, за исключением опечатки, в порядке. Вы не правильно его строите.   -  person juanchopanza    schedule 22.06.2012
comment
возможный дубликат неопределенной ссылки на G++ Cpp   -  person Bo Persson    schedule 22.06.2012
comment
@ Charles, benjamin, paranaix и всем спасибо за ваше предложение .... а в остальном код правильный .... без ошибки опечатки муравья ...   -  person Avinash Gopal    schedule 27.06.2012


Ответы (1)


Ошибка "неопределенная ссылка на..." является ошибкой компоновщика. Ваш код в порядке, но вы не связываете все свои исходные файлы с конечным продуктом, Phonenumber.cpp (или как вы его называете) не учитывается.

В моей системе

$ ls
Phonenumber.cpp  Phonenumber.h  main.cpp
$ g++ main.cpp
/tmp/cce0OaNt.o: In function `main':
main.cpp:(.text+0x40): undefined reference to `operator>>(std::basic_istream<char, std::char_traits<char> >&, Phonenumber&)'
main.cpp:(.text+0x51): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Phonenumber const&)'
collect2: ld returned 1 exit status

Обратите внимание, что Phonenumber.cpp не включен в компиляцию. Если вы включите его,

$ g++ main.cpp Phonenumber.cpp
$ ./a.out
Enter number in the form (123) 456-7890:
(555) 555-1234
(555)555-1234

Простого определения файла .cpp недостаточно, вы должны включить его при связывании. Это не относится к заголовочным файлам.

Диаграмма:

Source code ---compile--> Object files ---link--> Application

Phonenumber.cpp ----+
                    |---> Phonenumber.o ---+
                +---+                      |
                |                          |
Phonenumber.h --+                          +--> a.out
                |                          |
                +---+                      |
                    |---> main.o ----------+
main.cpp -----------+
person Dietrich Epp    schedule 22.06.2012
comment
stackoverflow действительно должен иметь значок «мастер искусства ascii», который будет награжден голосованием :) - person unkulunkulu; 22.06.2012
comment
Я не знаю, что такое джин. Задайте отдельный вопрос. - person Dietrich Epp; 27.06.2012