1

I snipped the irrelevant parts out of my class here. I don't know what I'm doing wrong, just trying to be able to cout << the object.

#include <iostream>

class Snipped
{

    public:
        friend std::ostream& operator<<(std::ostream& os, const Snipped& s);

    protected:
    private:
};

std::ostream& operator<<(std::ostream& os, const Snipped& s)
{
    os << "test";
    return os;
}

int main(int argc, char* argv[])
{
    Snipped* s = new Snipped();

        std::cout << s << std::endl << s;

    delete s;
    return 0;
}

Expected output:

test
test

Actual output:

0x12ae20
0x12ae20  (random memory location?)
user1139252
  • 261
  • 5
  • 11

3 Answers3

8
std::cout << s << std::endl << s;      

You are calling << with an address, you need to call it with object of type Snipped.
The line of code above won't call your overloaded operator function because the parameters of the overloaded function do not match.

You need to call:

std::cout << *s << std::endl << *s;      

This ensures your << overloaded operator function is called because the parameters match to it.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
6

Try

std::cout << *s << std::endl; 

By the way,

std::cout << s << std::endl; 

is not really a random memory location.

It is the actual memory address on the heap, in this case.

You can actually use that address to check the identity of an object.

That's useful while debugging, or in actual code. For example, if you look at assignment operators, you will often see:

class Foo
{
  Foo& operator=( const Foo& foo )
  {
    // use the identity principle 
    if ( &foo==this )
      return *this;  // so I don't waste CPU cycles copying to myself

    // ...really do copy here
    return *this;
  }
};
kfmfe04
  • 14,936
  • 14
  • 74
  • 140
  • You probably mean `=` and not `==` and I hope the example is for demonstration usage only.If overloading copy assignment I would rather recommend [Copy and Swap Idiom](http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) rather than the overhead of identity check. – Alok Save Jan 31 '12 at 06:45
2

Although just dereferencing the pointer (i.e. to use '*s' instead of 's') there is a bigger fish to fry! Unless there is a good reason for putting an object on the heap you shouldn't do so:

int main()
{
    Snipped s;
    std::cout << s << '\n' << s;
}

I found the use of new and more so delete quite rare in the programs I write. Aside from simpler code this conveniently also often yields faster programs. If you really need to allocate something on the heap, use some sort of a smart pointer to make sure the object is automatically released:

int main()
{
    std::unique_ptr<Snipped> s(new Snipped);
    std::cout << *s << '\n' << *s;
}

As a side note, don't use std::endl either unless you really intend to flush the stream: I found inappropriate use of std::endl to be the root cause of massive performance problems more than once. Sure most of the time it doesn't matter but in even more cases you don't care about the flush. If you don't like using '\n' or "\n" you can instead use a custom manipulator:

std::ostream& nl(std::ostream& out) { return out << '\n'; }

With this you can use nl instead of std::endl and don't suffer from always flushing the stream.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • +1 For the mention of performance problems due to `endl`. It is an often ignored performance issue.For those interested, [C++: “std::endl” vs “\n”](http://stackoverflow.com/questions/213907/c-stdendl-vs-n) would be a nice read. – Alok Save Jan 31 '12 at 06:57