overloading << for my class - c++

I'm trying to write the global function:
std::ostream& operator<<(std::ostream& out, const Str& str)
{
for(int i = 0; i < (int)str.mSize; ++i)
out << str.mBuffer[i];
return out;
}
For a custom string class. It compiles fine but when I go to link:
1>Str.obj : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Str const &)" (??6#YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV01#ABVStr###Z) already defined in Main.obj
1>C:\Users\Ron\Documents\Visual Studio 2010\Projects\App\Debug\App.exe : fatal error LNK1169: one or more multiply defined symbols found
How could multiple definitions for this exist? I just created the class Str.

I think you have defined twice in Main.cpp and Str.cpp, or may be .h files.
Write a str.h files which include the declaration of the Str class:
//str.h
class Str {
// your class stuff
friend std::ostream& operator<<(std::ostream& out, const Str& str);
};
then in str.cpp:
//str.cpp
#include "str.h"
std::ostream& operator<<(std::ostream& out, const Str& str) {
for(int i = 0; i < (int)str.mSize; ++i)
out << str.mBuffer[i];
return out;
}
Then you can use the function in you main.cpp.

If you define a function in a header file and include it twice, you'll get a multiple definition error, which you have.
To remedy this, declare the function in the header with a prototype and define it in a .cpp file.
Alternately, if you're trying to make a header only library, you could do
class Str {
// your class stuff
friend std::ostream& operator<<(std::ostream& out, const Str& str) {
for(int i = 0; i < (int)str.mSize; ++i)
out << str.mBuffer[i];
return out;
}
};

Did you put this in a header file?
The right way to do it is to declare it in the header file and put the code in a source file.

Related

Trouble understanding static in header files ( inline )

I've been working with static for quite a long time but now when the header files come I'm a little confused.
The main problem is this code :
#include <iostream>
#include <string>
#include <sstream>
#include <set>
#ifndef WORD_H
#define WORD_H
#include<unordered_map>
class Word
{
private:
std::string word;
int k;
static std::unordered_map<std::string, int> x;
public:
Word(std::string word) : word(word)
{
if (x.find(word) != x.end())
x.insert({ word , 0 });
else
{
x[word]++;
}
}
std::string getWord() const
{
return x.find(this->word)->first;
}
int getCount() const
{
return x.find(this->word)->second;
}
friend bool operator<(const Word& a, const Word& b);
};
bool operator<(const Word& a, const Word& b)
{
return a.getWord() < b.getWord();
}
#endif
std::ostream& operator<<(std::ostream& out, const Word& w) {
return out << w.getWord() << " " << w.getCount();
}
void printWordCounts(const std::string& line) {
std::istringstream lineIn(line);
std::set<Word> words;
std::string wordStr;
while (lineIn >> wordStr) {
words.insert(Word(wordStr));
}
for (Word w : words) {
std::cout << w << std::endl;
}
}
int main() {
std::string line;
std::getline(std::cin, line);
printWordCounts(line);
std::cout << "---" << std::endl;
std::getline(std::cin, line);
printWordCounts(line);
return 0;
}
I know that there is a problem with the static keyword, but what exactly is it?
Also, the error is one of my favourites. Those errors between linker and STL:
Error LNK2001 unresolved external symbol "private: static class std::unordered_map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,struct std::hash<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,struct std::equal_to<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int> > > Word::x" (?x#Word##0V?$unordered_map#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##HU?$hash#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###2#U?$equal_to#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###2#V?$allocator#U?$pair#$$CBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##H#std###2##std##A) ConsoleApplication63 C:\Users\Ivo\source\repos\ConsoleApplication63\ConsoleApplication63\ConsoleApplication63.obj 1
I hope that someone can give me an explanation.
You have only declared the static member x. You also need to define it outside the class like this:
std::unordered_map<std::string, int> Word::x;
From c++17, you can define x inside the class definition like this:
inline static std::unordered_map<std::string, int> x;
Static variable declarations in classes are identical to declaring a global variable in a header file, except it's 'symbol' lies within the namespace of the class and therefore access to it is protected with visibility levels. This means that like global variable declarations, static class variable declarations have 'weak' linkage and a compilation unit needs to define the symbol definition, so that the linker can tie the memory associated with the variable declarations in other files to exactly one variable.
Defining the static variable is done outside the class like so:
// <variable type> <class type>::<variable name>;
std::unordered_map<std::string, int> Word::x;
Note that only one .cpp file needs to define the variable

Template issues in C++

The issue I'm having here is class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Sadrzaj const &). I have searched far and wide on the Internet for a solution but could not find it. The issue occurs when I try to include Data.h in the main source file, the same happens with Content.h. Down below are the two header files for reference. Any help whatsoever is greatly appreciated. :-)
#pragma once
#include <iostream>
class Content
{
friend std::ostream& operator<<(std::ostream &str, const Content&);
public:
virtual void print(std::ostream&) const = 0;
};
std::ostream& operator<<(std::ostream &str, const Content& temp)
{
temp.print(str);
return str;
}
#pragma once
#include "Content.h"
template <class T>
class Data: public Content
{
public:
Data(const T&);
void print(std::ostream&) const override;
private:
T data;
};
template <class T>
Data<T>::Data(const T& data) : data(data) {}
template <class T>
void Data<T>::print(std::ostream& str) const { str << data; }
Okay, so the problem was that the << operator was defined in the "Content.h" header file. Simply by creating a new source file "Content.cpp" and defining it there, the problem was solved. If anyone knows why this solved the error, I would appreciate it very much if they would explain it to me, so that I don't make the same mistake again. :-)

Error: LINK2019: unresolved external symbol when using operator << in a namespace

I get the following error in windows.
I have a library L1 which has the following header file and it's implementation
namespace TC
{
namespace VT
{
enum Value
{
INVALID = 0,
Light = 1
};
std::ostream& operator<<(std::ostream& os, Value value);
}
}
There is another library L2 which uses the operator <<. The code compilers fine but results in a unresolved external symbol error. This means that operator << is not being located at link time.
Code in library L2.
bool Mock::Test(
TC::VT::Value venue )
{
string func(__func__);
cout << func
<< "venue = "
<< venue
<< endl;
return false;
}
cout line is the one causing the problem.
MockClient.obj : error LNK2019: unresolved external symbol "class std::basic_ostream > & __cdecl TC::VT::operator<<(class std::basic_ostream > &,enum TC::VT::Value)"
One of three things is happening here. Either you are not linking to the object file containing the definition of the operator, you have not provided a definition for the operator or the operator has not been defined properly. Since you have stated the object file is being linked you should make sure that your definition of the operator is correct. Your definition should look like the following
std::ostream& TC::VT::operator<<(std::ostream& os, Value value)
{
// ... your code here
return os;
}
Or it should be wrapped in the namespace
namespace TC
{
namespace VT
{
std::ostream& TC::VT::operator<<(std::ostream& os, Value value)
{
// ... your code here
return os;
}
}
}

Fatal error LNK1120 in C++

That's my program written in C++ (OOP):
#include <iostream>
#include <string>
using namespace std;
class book {
string name,gvari;
double cost;
int year;
public:
book(){};
book(string a, string b, double c, int d) { a=name;b=gvari;c=cost;d=year; }
~book() {}
double setprice(double a) { return a=cost; }
friend ostream& operator <<(ostream& , book&);
void printbook(){
cout<<"wignis saxeli "<<name<<endl;
cout<<"wignis avtori "<<gvari<<endl;
cout<<"girebuleba "<<cost<<endl;
cout<<"weli "<<year<<endl;
}
};
ostream& operator <<(ostream& out, book& a){
out<<"wignis saxeli "<<a.name<<endl;
out<<"wignis avtori "<<a.gvari<<endl;
out<<"girebuleba "<<a.cost<<endl;
out<<"weli "<<a.year<<endl;
return out;
}
class library_card : public book {
string nomeri;
int raod;
public:
library_card(){};
library_card( string a, int b){a=nomeri;b=raod;}
~library_card();
void printcard(){
cout<<"katalogis nomeri "<<nomeri<<endl;
cout<<"gacemis raodenoba "<<raod<<endl;
}
friend ostream& operator <<(ostream& , library_card&);
};
ostream& operator <<(ostream& out, library_card& b) {
out<<"katalogis nomeri "<<b.nomeri<<endl;
out<<"gacemis raodenoba "<<b.raod<<endl;
return out;
}
int main() {
book A("robizon kruno","giorgi",15,1992);
library_card B("910CPP",123);
cout<<A;
cout<<B;
A.setprice(15);
cout<<B;
system("pause");
return 0;
}
//P.S.
//B.printcard();
//A.printbook();
// As I've overloaded the "<<" operators, I've removed these two lines and put "cout<<A" "cout<<B". I hope, I'm right. By the way, error isn't related to these ones.
Here is the error, it may help you:
1>Neyw.obj : error LNK2019: unresolved external symbol "public: __thiscall library_card::~library_card(void)" (??1library_card##QAE#XZ) referenced in function _main
1>c:\users\geo\documents\visual studio 2010\Projects\Newww\Debug\Newww.exe : fatal error LNK1120: 1 unresolved externals
1>Build FAILED.
The problem is I can't figure out what's wrong with the code.. There are two classes, the main one, book, and the successor class, library_card. Why does it give me such an error?
Replace
~library_card();
with
~library_card() {}
You haven't implemented the destructor and this is exactly what your linker is saying.
Or you can remove this string as well if you don't know why you need this destructor.
There's no function body for ~library_card();. Just remove that destructor, or populate it, whichever you like.
Whilst you're there, have a read about virtual destructors, and consider whether your classes need them.

C++ overloading >> and << operators

I've been trying to overload the >> and << operators in C++, and I keep getting:
Error 2 error LNK2019: unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class ArrayStorage &)" (??5#YAAAV?$basic_istream#DU?$char_traits#D#std###std##AAV01#AAVArrayStorage###Z) referenced in function _main G:\Desktop\ACW\08227_ACW2_TestHarnessSolution\main.obj
The way I'm doing it is:
//.h file
friend ostream& operator<<(ostream &sout, ArrayStorage &Astor);
friend istream& operator>>(istream &sin, ArrayStorage &Astor);
//cpp file
ofstream& operator<< (ofstream &sout, ArrayStorage &astor)
{
astor.write(sout);
return sout;
}
ifstream& operator>> (ifstream &sin, ArrayStorage &astor)
{
astor.read(sin);
return sin;
}
A friend of mine told me to take the "friend" off the declaration in the header file and move it to outside the class, but I still get the same error. It's probably something easy, but I can't figure out what's not working.
Your declarations have parameter and return types of istream and ostream; but the definitions have ifstream and ofstream.
Remove the fs from the definitions and all should be fine.
The friend declarations are fine as they are (assuming they're inside a class definition); they declare functions in the surrounding namespace. However, if read and write are public, then you might consider unfriending them since they won't need privileged access in that case.