xml_attribute.h
#pragma once
#ifndef XML_ATTRIBUTET_H
#define XML_ATTRIBUTET_H
#include <string>
#include <iostream>
struct XML_AttributeT{
std::string tag;
std::string value;
//constructors
explicit XML_AttributeT(std::string const& tag, std::string const& value);
explicit XML_AttributeT(void);
//overloaded extraction operator
friend std::ostream& operator << (std::ostream &out, XML_AttributeT const& attribute);
};
#endif
xml_attribute.cpp
#include "xml_attribute.h"
//Constructors
XML_AttributeT::XML_AttributeT(std::string const& tag_, std::string const& value_)
: tag{tag_}
, value{value_}
{}
XML_AttributeT::XML_AttributeT(void){}
//overloaded extraction operator
std::ostream& operator << (std::ostream &out, XML_AttributeT const attribute){
return out << attribute.tag << "=" << attribute.value;
}
driver.cpp
#include <iostream>
#include <cstdlib>
#include "xml_attribute.h"
int main(){
using namespace std;
XML_AttributeT a();
cout << a << endl;
return EXIT_SUCCESS;
}
The output from the driver is a '1' but I want it to be an '=' sign.
Why is it outputting the reference to a?
If I change XML_AttributeT a(); to XML_AttributeT a; it doesn't even compile.
What did I do wrong?
chris is correct. Your initial issue is that XML_AttributeT a() is interpreted as a function declaration. clang++ will actually warn you of this:
Untitled.cpp:33:21: warning: empty parentheses interpreted as a function declaration [-Wvexing-parse]
XML_AttributeT a();
You can use a{} instead to fix this.
At this point you get a new error:
Untitled.cpp:34:10: error: use of overloaded operator '<<' is ambiguous (with operand types 'ostream' (aka 'basic_ostream<char>') and 'XML_AttributeT')
cout << a << endl;
This is because of what jogojapan said. Your implemented operator<< is using XML_AttributeT const as the attribute type instead of XML_AttributeT const &. If you fix that, then it compiles and gives you the result you want.
Related
I am fairly new to classes. I created a class called Counter which basically creates a counter object and has certain data members and function members associated with it.
The header file for the class is:
#ifndef c
#define c
#include <iostream>
#include <string>
#include <vector>
using std::vector; using std::string; using std::ostream;
class Counter{
int v_;
public:
vector<string> log_;
int initialized_;
Counter(int);
int value();
int get_v() const { return v_; } //getter
void set_v(int val) { v_ = val; } //setter
friend ostream & operator<<(ostream &, Counter &);
friend Counter operator+(const Counter &, const Counter &);
};
ostream & operator<<(ostream &, Counter &);
Counter operator+(const Counter &, const Counter &);
#endif
and the cpp implementation file looks like this:
#include "counter.h"
#include <iostream>
#include <vector>
#include <string>
using std::string; using std::vector; using std::ostream;
Counter::Counter(int a){
v_ = a;
initialized_ = a;
log_.push_back("Constructor called with a " + std::to_string(a));
}
int Counter::value(){
log_.push_back("value called. returned a " + std::to_string(v_));
return (v_--);
}
ostream & operator<<(ostream & out, Counter & c){
c.log_.push_back("<< called."); //line 1
out << "Counter("<< c.initialized_ << ")#" << c.v_; //line 2
return out;
}
Counter operator+(const Counter & c_one, const Counter & c_two){
Counter c_three(c_one.initialized_ + c_two.initialized_);
c_three.set_v(c_one.get_v()+c_two.get_v());
return c_three;
}
When I compile the file I get bombarded with expected primary-expression before ‘.’ token in line 1 and line 2 of the "<<" operator overloaded function. I really have no idea as to why this is happening. Any help?
What is c? You've defined it as nothing and then you use
c.log_.push_back(...)
Which the preprocessor changes to
.log_.push_back(...)
I'm not sure what you're trying to do but the error clearly states it's looking for an expression before the period, where it appears you have none.
Just got into C++ and I have a quick question.
After compiling with
g++ *.cpp -o output
I receive this error:
error: 'ostream' in 'class Dollar' does not name a type
These are my three files:
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
Thank you for your time, and everything helps!
You have a number of errors in the code.
You heavily use using namespace std. This is a bad practice. In particular, this led to the error you faced: you don't have using namespace std in Dollar.h, thus the compiler has no idea what ostream means. Either put using namespace std in Dollar.h too, or better just stop using it and specify the std namespace directly, as in std::ostream.
You use std::ostream in your headers, but you don't include the corresponding standard library header <ostream> in them (<ostream> contains the definition of std::ostream class; for the full I/O library include <iostream>). A really good practice is to include all the dependencies of the header in the header itself, so that it is self-contained and can be safely included anywhere.
You are implementing a stream output operator with signature std::ostream & operator << (std::ostream &, Dollar const &), which is perfectly valid. However, you call it for a pointer to type Dollar. You should rather call it with the object itself, not the pointer, so you should dereference the pointer: std::cout << *cp;.
You implemented the output operator for the Dollar class, but use it for a variable of type Currency: this won't work. There is a way to do this - there do exist virtual methods for this exact reason. However, in this case the operator is a free function, thus it cannot be virtual. So, you should probably add a virtual print method to your Currency class, implement it in Dollar, and call it from output operator:
#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
}
You need to #include <iostream> within Dollar.h so that your std::ostream & operator is resolved by the compiler.
I have a class Graph with constructor and overloaded operator <<, graph.h:
class Graph
{
private:
vector<int> setOfVertices;
public:
Graph(ifstream &); //konstruktor ze souboru
friend ofstream & operator<<(ofstream&, const Graph &);
};
the definition of constructor(not important for minimal example) and operator << are in separated file graph.cpp:
ofstream & operator<<(ofstream& outputStream, const Graph & graphToPrint)
{
//not important for minimal example
return outputStream;
}
When I try to call operator << in main.cpp:
#include <iostream>
#include <fstream>
#include "graph.h"
using namespace std;
int main()
{
ifstream myFile ("example.txt");
Graph * G = new Graph(myFile);
cout << *G;
return 0;
}
I get an error
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'Graph' (or there is no acceptable conversion)
I didn't manage to locate the mistake in the code by myself, I will be thankful for every piece of advice.
std::cout is a global object of type std::ostream not std::ofstream. std::ofstream is a derivative of std::ostream. See http://en.cppreference.com/w/cpp/io/cout
So, modify your friend function (operator) to
friend ostream & operator<<(ostream&, const Graph &);
I get this when i try to compile:
../Monster.h:26:9: error: ‘int ProjectIV::Monster::con’ is private
`int con;`
^
../Monster.cpp:17:39: error: within this context
cout << "Constitution: " << monster.con << endl;
^
make: * [Monster.o] Error 1
From what I understand making operator<< a friend should allow it to access int con. What am I not seeing.
Monster.h:
#ifndef MONSTER_H_
#define MONSTER_H_
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;
#include <string>
using std::string;
namespace ProjectIV
{
class Monster
{
friend ostream &operator<< (ostream &out, const Monster &monster);
public:
Monster(int con);
private:
int con;
};
} /* namespace ProjectIV */
#endif /* MONSTER_H_ */
Monster.cpp:
#include "Monster.h"
ostream &operator<< (ostream &out, const ProjectIV::Monster &monster)
{
cout << "Constitution: " << monster.con << endl;
return out;
}
ProjectIV::Monster::Monster(int con): con(con)
{}
main.cpp:
#include "Monster.h"
using namespace ProjectIV;
int main()
{
Monster Gojira(140);
cout << Gojira << endl;
return 0;
}
This:
ostream& operator<<(ostream& out, const ProjectIV::Monster& monster)
should be:
ostream& ProjectIV::operator<<(ostream& out, const ProjectIV::Monster& monster)
Here your not working example, and here is the working one.
Also, as per AndreyT's comment, you should add a function declaration before the friend declaration:
namespace ProjectIV {
class Monster {
friend ostream& operator<<(ostream& out, const Monster& monster);
public:
Monster(int con);
private:
int con;
};
ostream& operator<<(ostream& out, const Monster& monster);
// ^^^ this
}
There are two problems with your code.
Firstly, the friend declaration inside Monster class refers to ProjectIV::operator << function. It is ProjectIV::operator << that will become the friend of Monster. What you defined in your Monster.cpp file is actually a ::operator <<. This is a completely different function that is not a friend of Monster. This is why you get the error.
So, you need to decide what function you want to make a friend - the one in global namespace or the one in ProjectIV namespace - and act accordingly.
If you want to make your operator << a member of ProjectIV namespace, you run into the second problem. Friend declarations refer to member of enclosing namespace, but they don't introduce the corresponding declarations into the enclosing namespace. It is still your responsibility to add a declaration for operator << in ProjectIV
namespace ProjectIV
{
class Monster
{
friend ostream &operator<< (ostream &out, const Monster &monster);
public:
Monster(int con);
private:
int con;
};
ostream &operator<< (ostream &out, const Monster &monster);
} /* namespace ProjectIV */
and then later define it as a member of ProjectIV
ostream &ProjectIV::operator<< (ostream &out, const ProjectIV::Monster &monster)
{
cout << "Constitution: " << monster.con << endl;
return out;
}
I am a C++ beginner ( came from Java ). I have the following code:
//#include <boost/algorithm/string.hpp>
#include <iostream>
#include <math.h>
#include <vector>
#include <string.h>
#include <string>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <memory>
#include <assert.h>
#include <cctype>
using namespace std;
class Point{
private:
int x;
int y;
public:
Point(int x,int y){
this->x=x;
this->y=y;
}
int getX(){
return x;
}
int getY(){
return y;
}
operator const char*(){
return toString().c_str();
}
string toString(){
ostringstream stream;
stream<<"( "<<x<<", "<<y<<" )";
return stream.str();
}
};
class Line{
private:
Point p1=Point(0,0);
Point p2=Point(0,0);
public:
Line(Point p1, Point p2){
this->p1=p1;
this->p2=p2;
}
Point getP1(){
return p1;
}
Point getP2(){
return p2;
}
operator const char*(){
ostringstream stream;
stream<<"[ "<<p1<<" -> "<<p2<<" ]";
return stream.str().c_str();
}
// operator const char*(){
// ostringstream stream;
// stream<<"[ "<<p1<<" -> ";
// stream<<p2<<" ]";
// return stream.str().c_str();
// }
};
int main()
{
Line line=Line(Point(1,2), Point(3,4));
cout<<line<<endl;
cout<<"\nProgram exited successfully."<<endl;
return 0;
}
I have redefined the operator const* so that I can use cout<
But, If I run the program as it is now, with the second block commented out ( I have 2 versions of operator const*, and by default the second one is commented out ) ,it will display
[ (1, 2) -> (1, 2) ]
But when running with the second block uncommented, the output is as expected:
[ (1, 2) -> (3, 4) ]
The issue seems to occur when I display both Point objects in the same line ( some kind of chaining, though I don't know if chaining is the right word here )
My question, is,why is this happening?
UPDATE
I have added the std::ostream& operator << function to my Line class but now I'm receiving the following errors:
/home/ryu/qt_workspace/hello/main.cpp:67: error: 'std::ostream& Line::operator<<(std::ostream&, const Line&)' must take exactly one argument
/home/ryu/qt_workspace/hello/main.cpp:77: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
Regards,
Aurelian
If you want to use cout <<, there is a more direct way to do that.
Add this function to Line.
friend std::ostream& operator << ( std::ostream & os, const Line & l ){
os << "[ " << l.p1 << " -> " << l.p2 << " ]";
return os;
}
You should also note that your approach was returning invalid memory - this is a significant way that Java differs from C++.
return stream.str().c_str(); // Danger!
stream was declared in operator const char*() which limits its lifetime to that function. It is destroyed when that scope is exited. As a result, you are returning a pointer to something that no longer exists.
actually I think with C++11 returning the string by value is perfectly fine, so you can do the transfer there instead of using the cstring underneath.
What are move semantics?