1

I have my custom class in C++:

Class MyClass
{
  private std::ofstream logfile("D:\my.txt",std::ios_base::app);
}

I want to be able to write following:

MyClass *my = new MyClass();
int a = 3;
my <<  "Hello World1" << a << std::endl;
my << L"Hello World2" << a << std::endl;

Result should be that everything will be saved (redirected) into the private stream (file) named "logfile".

Is it possible? I was trying to use cca this, but without success: https://www.tutorialspoint.com/cplusplus/input_output_operators_overloading.htm

Racky
  • 1,173
  • 18
  • 24
  • 1
    Would your goal also be reached by `(*my) << "Hello World1" << a << std::endl;`? – Yunnosch Sep 28 '17 at 07:04
  • That tutorial you link to is how to make it possible to do e.g. `std::cout << *my << ...`. Not how you overload the shift operators for your own class. You need to overload the [bitwise arithmetic operators](http://en.cppreference.com/w/cpp/language/operators#Bitwise_arithmetic_operators) `<<` and `>>` like a [binary arithmetic operator](http://en.cppreference.com/w/cpp/language/operators#Binary_arithmetic_operators). There should be plenty of tutorials on that too if you just continue to search a little. – Some programmer dude Sep 28 '17 at 07:04
  • @Yunnosch: Any similar solution would be OK for now. Once I know how it works I can enhance it. Thanks. – Racky Sep 28 '17 at 07:07
  • @Someprogrammerdude: Thanks for clarification what I am actually looking for :-) I know literally nothing about these operators so I will search again. – Racky Sep 28 '17 at 07:10
  • I think most [good beginners books](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) should have examples as well. – Some programmer dude Sep 28 '17 at 07:11
  • So I now found a temporary solution - it is a wrapper for vsprintf(). Inspiration on how to write method with unlimited nr of arguments was found here: https://code.woboq.org/userspace/glibc/stdio-common/sprintf.c.html#21 – Racky Sep 28 '17 at 09:14

1 Answers1

1

You can use something like this:

class MyClass
{
public:
    MyClass() : logfile("logfile.log", std::ios::app) {}

    template<typename T>
    friend MyClass& operator<<(MyClass& obj, const T& data);

    private:
        std::ofstream logfile;
};

template<typename T>
MyClass& operator<<(MyClass& obj, const T& data) {
    obj.logfile << data;
    return obj;
}

int main() {
    MyClass obj;

    obj << "Hello\n"; 
    obj << 123 << " World\n";
}

The templated operator << accepts everything that compiles and redirects it to the ofstream inside the MyClass object. The << operator has to be declared as friend of MyClass since it is defined outside it and it has to be able to access the private logfile object.

And as mentioned in the comments, if you access your MyClass object through a pointer you need to dereference it before using the << operator:

MyClass *obj = new MyClass;

*obj << "Hello\n"; 
*obj << 123 << " World\n";

Anyway you have some syntax errors in your class definition (maybe it was just for example purposes?).

Andrea Corbelli
  • 329
  • 6
  • 12
  • Hi, thanks for your solution, I will test it right away. And you are right, my code was not correct C++, it was just a pseudo code that was supposed to describe my situation. – Racky Sep 28 '17 at 09:16
  • And can be the following error caused by older C++? I do not have C++11, but older. The problem is when I write: *obj << "Hello\n"; MyLog.obj : error LNK2019: unresolved external symbol "class MyClass & __cdecl operator<<(class MyClass &,char const (&)[7])" (??$?6$$BY06$$CBD@@YAAAVMyClass@@AAV0@AAY06$$CBD@Z) referenced in function _wmain – Racky Sep 28 '17 at 09:34
  • So when I copy your solution into 1 cpp file it works. I probably copied it incorrectly to my project. Thanks for working example. – Racky Sep 28 '17 at 09:45
  • Great! Glad i helped. – Andrea Corbelli Sep 28 '17 at 12:52