why can't we create our own ostream object - c++

If cout is an object of ostream class, then why can't we declare our own object, say, 'out' from the same class. i.e, isn't the following code supposed to work??
#include<iostream>
using namespace std;
int main()
{
ostream out;
out<<"something";
}
or otherwise
#include<iostream>
using namespace std;
int main()
{
ostream_withassign out;
out<<"something";
}

Stream objects require a buffer to send data to the external device. The standard output stream object, std::cout, is initialized with a buffer the encapsulates transport to wherever your output appears. Here is a contrived example:
std::ostream cout(/* buffer */);
To make your own stream object that pretends to be the standard stream object, you can simply pass the buffer of std::cout to its constructor. Note that I wouldn't recommend doing this in practice:
std::ostream copy(std::cout.rdbuf()); // Note: not a *real* copy
copy << "Hello World";

You didn't set the ostream object(what does this stream output to), of course you can't use it.
http://www.cplusplus.com/reference/iostream/ostream/ostream/
i.e.
// ostream constructor
#include <iostream>
#include <fstream>
using namespace std;
int main () {
filebuf fb;
fb.open ("test.txt",ios::out);
ostream os(&fb);
os << "Test sentence\n";
fb.close();
return 0;
}

ostream class is derived from ios class.
Constructor of ios class looks like below.
public: explicit ios (streambuf* sb);
protected: ios();
Which means default constructor of ios is protected and hence you can't create object using default constructor of ostream.
Only way left to create object of ostream is using streambuf sb* argument.
std::ostream my_obj(std::cout.rdbuf());
Similarly, you can't pass ostream objects by value.
Reason
ios is derived from ios_base.
Its copy constructor is private.
protected: ios_base();
private: ios_base (const ios_base&);

you can do this only:
#include <iostream>
std::ostream& gvar = std::cout << "Hello world" << std::endl;
int main() {}
from:
http://xazax.web.elte.hu/

Related

ostream in class does not have a type

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.

Making a class templatized on stream handle both std::cout and an std::ofstream

I want to write a class StreamContainer that is templatized on Stream:
#ifndef STREAMCONTAINER_HPP
#define STREAMCONTAINER_HPP
#include <string>
#include <iostream>
template<typename Stream>
class StreamContainer
{
public:
StreamContainer(std::ostream& os)
: m_stream(os) {}
private:
Stream & m_stream;
};
#endif
I would think that the following client code would work:
#include "StreamContainer.hpp"
#include <fstream>
int main(int argc, char argv[])
{
std::ofstream ofs;
ofs.open("c:\\code\\temp.txt");
StreamContainer<decltype(std::cout)> coutContainer(std::cout); // C2439
StreamContainer<std::ofstream> fileContainer(ofs); // C2664
}
But that doesn't work, at least in Visual C++ 2015. Trying to pass std::cout causes error C2439 (member could not be initialized) and trying to pass a std::ofstream object causes error C2664 (std::basic_ofstream constructor can't convert argument from std::basic_ostream to const char *). I've also tried using a move constructor, but had other issues with that. Any suggestions as to how to resolve this would be greatly appreciated.
This:
StreamContainer(std::ostream& os)
should be:
StreamContainer(Stream& os)
Otherwise, your ofstream instantiation is trying to take an ofstream& reference (m_stream) to an ostream (os). The other direction is fine, but this is assigning a base class object to a derived reference.
Since you can't deduce class template arguments from constructor arguments, this is a good use-case for just introducing a factory function:
template <typename Stream>
StreamContainer<Stream> make_container(Stream& s) {
return StreamContainer<Stream>{s};
}
so that you don't have to repeat the arguments or, worse, use decltype:
auto coutContainer = make_container(std::cout);
auto fileContainer = make_container(ofs);
Or, really, both can just be ostream& if you don't need any of the type-specifics.

regarding streams in c++

I want to use file streams and consol output stream. In constructor, I want to initialize with either file or consol output stream depending on parameter passed to constructor. Then I will have another function in class which will redirect output to that stream. what will be the code for it? I am trying with the below code which is not working.
Any other design suggestions are welcome.
class Test
{
private:
std::ios *obj;
std::ofstream file;
std::ostream cout1;
public:
// Test(){}
Test(char choice[])
{
if(choice=="file")
{
obj=new ofstream();
obj->open("temp.txt");
}
else
obj=new ostream();
}
void printarray()
{
for(int i=0;i<5;i++)
(*obj)<<"\n \n"<<"HI"
}
};
Something like this should work:
#include <iostream>
#include <fstream>
#include <string>
class Test
{
private:
std::ofstream file;
std::ostream& obj;
public:
// Use overloaded constructors. When the default constructor is used,
// use std::cout. When the constructor with string is used, use the argument
// as the file to write to.
Test() : obj(std::cout) {}
Test(std::string const& f) : file(f.c_str()), obj(file) {}
void printarray()
{
for(int i=0;i<5;i++)
obj<<"\n " << "HI" << " \n";
}
};
int main()
{
Test a;
a.printarray();
Test b("out.txt");
b.printarray();
}
PS Look at the changes to printarray. What you were trying, with %s, is good for the printf family of functions but not for std::ostream.
Any other design suggestions are welcome.
Two of these members are useless:
std::ios *obj;
std::ofstream file;
std::ostream cout1;
You can't do anything with a std::ios, a std::ostream that isn't associated with a streambuf is useless, and you never use file or cout1 anyway!
You want:
std::ofstream file;
std::ostream& out;
as shown in R Sahu's answer, and write to out.
Test(char choice[])
{
if(choice=="file")
This doesn't work, you need to use strcmp to compare char strings. You should probably use std::string not char*.

How do I change a C++ output stream to refer to cout?

I have a class that I want to give an output stream as a member to, to wit:
class GameBase {
protected:
ofstream m_OutputWriter;
...
}
There is a method in this class that takes a string argument and opens m_OutputWriter to point to that file, so data may be output to that file by using the standard << operator;
However, what I would like is to make the stream point to cout by default, so that if the output path is not specified, output goes to the console output instead of to a file, and it will be completely transparent by the calling class, who would use
m_OutputWriter << data << endl;
to output the data to the predetermined destination. Yet, I have tried a couple of the other examples here, and none of them exactly seem to fit what I'm trying to do.
What am I missing here?
Why does the stream need to be a member?
struct GameBase {
void out(std::ostream& out = std::cout);
// ...
};
In addition to having an std::ofstream as a member, I would use a function that returns an std::ostream&.
For example:
class GameBase {
std::ofstream m_OutputWriter;
protected:
std::ostream& getOutputWriter() {
if (m_OutputWriter)
return m_OutputWriter;
else
return std::cout;
}
...
}
A fully-functioning example:
#include <iostream>
#include <ostream>
std::ostream& get() {
return std::cout;
}
int main() {
get() << "Hello world!\n";
}

Operator << overload in c++

#include <iostream>
#include <fstream>
class obj
{
public:
int i;
friend ostream& operator<<(ostream& stream, obj o);
}
void main()
{
obj o;
ofstream fout("data.txt");
fout<<o;
fout.close();
}
This is the my code, am getting error.
error : ostream : ambiguous symbol.
any one can help me.
You need to specify the namespace. Prefix ostream with std - i.e. std::ostream
Also, you should pass the obj type by const reference to the operator:
friend ostream& operator<<(ostream& stream, const obj& o);
You didn't use namespace std (using namespace std is habit anyway) so the compiler doesn't know what on earth an ostream is.In addition to that, you didn't actually define operator<<, only declared it, so even if it recognizes it, it won't know what to do since you didn't tell it.
As I see it you need to
Add
using std::ostream;
using std::ofstream;
Add a ; after the class declaration
Povide an implementation for the << operator.
In the end you should end up with something like:
#include <iostream>
#include <fstream>
using std::ostream;
using std::ofstream;
class obj
{
public:
int i;
friend ostream& operator<<(ostream& stream, const obj& o);
};
ostream& operator<<(ostream& stream, const obj& o)
{
std::cout << o.i;
return stream;
}
int main()
{
obj o;
ofstream fout("data.txt");
fout << o;
fout.close();
}
ofstream is in namespace std, so you need to declare fout like this:
std::ofstream fout("data.txt");
I'll assume you simply omitted the definition of your operator<< function for simplicity. Obviously, you'll need to write the body of that function for your next line to compile.
ostream is a member of the std:: namespace, so either put a using namespace std; before your class declaration or explicitly refer to it with std::ostream.
Consider passing your object in as a reference otherwise a new obj object will be created each time via the copy constructor.
friend ostream& operator<<(ostream& stream, obj& o);