- Forum
- General C++ Programming
- Linking error on overloaded operator<<
Linking error on overloaded operator<<
I have been writing a small static library with a Jeton class. This class has an overloaded operator<<. Here is the code:
In Jeton class:
Jeton.h:
|
|
Jeton.cpp:
|
|
And finally, main.cpp:
|
|
When I compile this, I get the following liker error:
undefined reference to `pXbase::operator<<(std::ostream&, pXbase::Jeton const&)'
I have carefully looked at the code but found nothing that could generate this error… My library is correctly liked to the main since every other method work. Can anyone tell me what is wrong with this?
Thanks!
Last edited on
Try enclosing the code in file Jeton.cpp inside the namespace pXbase.
@Chervil: Thanks, it did work with your suggestion. But… what’s going on here? It did enclose the operator in the pXbase namespace upon declaration. Why do I have to do it it at definition as well?
I’m not sure of the proper technical explanation, however, as you said, the function was declared within that namespace, so it seems reasonable that the definition should be too. Otherwise it would belong to the global namespace.
Ok thanks!
@BobMorane: I was trying to replicate your code and am getting error messages from the header and implementation files compilations:
error: 'ostream' in namespace 'std' does not name a type
I think I understand why this is happening, at least in the header file — Jeton is enclosed entirely within namespace pXbase and therefore cannot reach namespace std despite the scope resolution std::ostream. Did you face any similar issues?
@gunnerfunner: Thanks for the check. I did not see that error message here. After I applied Chervil’s suggestion, everything compiled/linked fine. Also, I think it’s worth mentioning that my compiler (gcc) is set to see warning as errors.
Personnaly,
Jeton is enclosed entirely within namespace pXbase and therefore cannot reach namespace std despite the scope resolution std::ostream.
I don’t think this should be. You can refer to other namespaces inside a particular namespace. Maybe I don’t understand your point precisely?
Thanks
Last edited on
@gunnerfunner
Did you put #include <iostream>
at the start of Jeton.h ?
No, I knew #include <iostream>
might be a possible solution but did not want to do that in the header file. But it seems OP managed to get by w/o it
@gunnerfunner: is it working now?
Well, if the header uses something like std::ostream then it must have the <iostream> header available. I can’t see a problem with putting it at the start of «Jeton.h», but if you don’t, you need to make sure that whichever file makes use of header «Jeton.h» first includes the required standard headers.
if the header uses something like std::ostream then it must have the <iostream> header available
… not always but in this case, sure because of namespace pXbase. I was just wondering if we could do w/o including the whole library in the header but it seems we can’t for this example
The program won’t compile if there is a reference to std::
something without having the corresponding header available somewhere. Sometimes one header includes another, so it isn’t always obvious which headers are visible.
User-defined headers are generally included inside another file, which might incidentally include some other headers, but one way or another that’s the only way it can compile.
> I was just wondering if we could do w/o including the whole library in the header
To minimise dependencies:
In the header:
#include <iosfwd>
and declare the functions
In the implementation file:
#include <iostream>
(plus
#include <fstream>
etc. as required) and define the functions.
eg. header file:
|
|
implementation file:
|
|
@JLBorges: Brilliant! Thank you
Topic archived. No new replies allowed.
Просто попал в C ++ и у меня есть быстрый вопрос.
После компиляции с
g++ *.cpp -o output
Я получаю эту ошибку:
error: 'ostream' in 'class Dollar' does not name a type
Это мои три файла:
main.cpp
#include <iostream>
#include "Currency.h"#include "Dollar.h"
using namespace std;
int main(void) {
Currency *cp = new Dollar;
// I want this to print "printed in Dollar in overloaded << operator"cout << cp;
return 0;
}
Dollar.cpp
#include <iostream>
#include "Dollar.h"
using namespace std;
void Dollar::show() {
cout << "printed in Dollar";
}
ostream & operator << (ostream &out, const Dollar &d) {
out << "printed in Dollar in overloaded << operator";
}
Dollar.h
#include "Currency.h"
#ifndef DOLLAR_H
#define DOLLAR_H
class Dollar: public Currency {
public:
void show();
};
ostream & operator << (ostream &out, const Dollar &d);
#endif
Спасибо за ваше время, и все помогает!
2
Решение
У вас есть несколько ошибок в коде.
- Вы интенсивно используете
using namespace std
, Это плохая практика. В частности, это привело к ошибке, с которой вы столкнулись: у вас нетusing namespace std
вDollar.h
Таким образом, компилятор понятия не имеет, чтоostream
средства. Либо поставитьusing namespace std
вDollar.h
тоже, или лучше просто прекратить использовать его и указатьstd
пространство имен напрямую, как вstd::ostream
, - Ты используешь
std::ostream
в ваших заголовках, но вы не включаете соответствующий стандартный заголовок библиотеки<ostream>
в них (<ostream>
содержит определениеstd::ostream
учебный класс; для полной библиотеки ввода / вывода включить<iostream>
). Хорошей практикой является включение всех зависимостей заголовка в сам заголовок, чтобы он был автономным и мог быть безопасно включен где угодно. - Вы реализуете оператор вывода потока с подписью
std::ostream & operator << (std::ostream &, Dollar const &)
, что совершенно справедливо. Тем не менее, вы называете это для указатель печататьDollar
, Вы должны скорее назвать это с объект сам по себе, а не указатель, поэтому вы должны разыменовать указатель:std::cout << *cp;
, -
Вы реализовали оператор вывода для
Dollar
класс, но используйте его для переменной типаCurrency
: это не сработает. Есть способ сделать это — существуют виртуальные методы именно по этой причине. Однако в этом случае оператор является свободной функцией, поэтому он не может быть виртуальным. Итак, вам, вероятно, следует добавить виртуальныйprint
метод к вашемуCurrency
класс, реализовать его вDollar
и вызвать его из оператора вывода:#include <iostream> class Currency { public: virtual void print (std::ostream &) const = 0; }; class Dollar : public Currency { void print (std::ostream & out) const override { out << "A dollar"; } }; std::ostream & operator << (std::ostream & out, Currency const & c) { c.print(out); return out; } int main(/* void is redundant here */) { Currency *cp = new Dollar; std::cout << *cp; // return 0 is redundant in main }
6
Другие решения
Вам нужно #include <iostream>
в пределах Dollar.h, чтобы ваш std::ostream & operator
разрешается компилятором.
0
4 / 4 / 2
Регистрация: 27.03.2013
Сообщений: 110
1
12.01.2014, 16:28. Показов 6866. Ответов 3
C++ | ||
|
— вот эта строка.
Весь код:
C++ | ||
|
Ну, так же там есть подобные ошибки.
Лог:
C++ | ||
|
Подскажите, пожалуйста, где, что, как?
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0