2012-01-31 104 views
1

我在这里剪掉了我的课程中不相关的部分。我不知道我在做什么错,只是试图能够对对象产生影响。试图超载cout <<运算符但它不起作用

#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; 
} 

预期输出:

test 
test 

实际输出:

0x12ae20 
0x12ae20 (random memory location?) 

回答

6

尝试

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

顺便说一句,

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

是不是一个真正的随机内存位置。

这是在这种情况下堆上的实际内存地址。

您实际上可以使用该地址来检查对象的身份。

这在调试或实际代码时很有用。 例如,如果你看一下赋值操作符,你会经常看到:

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; 
    } 
}; 
+0

你可能意指'='而不是'==',我希望这个例子仅用于演示用法。如果超载复制分配,我宁愿推荐[复制和交换成语](http://stackoverflow.com/questions)/3279543/what-the-copy-and-swap-idiom)而不是身份检查的开销。 – 2012-01-31 06:45:40

+0

@Als thx修复 – kfmfe04 2012-01-31 06:53:17

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

您与地址调用<<,你需要Snipped类型的对象调用它。
上面的代码行不会调用您的重载操作符函数,因为重载函数的参数不匹配。

你需要调用:

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

这确保了<<重载的运算符函数被调用,因为参数与之匹配。

2

虽然只是解引用指针(即使用“* S”,而不是“S”)有更大的鱼鱼苗!除非有充分的理由把一个对象,你不应该这样做堆:

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

我发现我写的程序使用new,更使delete相当罕见。除了更简单的代码之外,这种方法通常也会产生更快的程序。如果你真的需要在堆中分配的东西,使用某种智能指针,以确保该对象被自动释放:

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

作为一个侧面说明,不要用std::endl或者,除非你真的打算冲洗流:我发现不当使用std::endl不止一次成为大规模性能问题的根本原因。大多数情况下,这并不重要,但在更多情况下,您并不在乎冲水。如果你不喜欢使用'\n'"\n"可以改为使用自定义的机械手:

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

有了这个,你可以使用nl代替std::endl并不会从总刷新流受到影响。

+0

+1提及由于'endl'引起的性能问题。这是一个经常被忽略的性能问题。对于那些有兴趣的人,[C++:“std :: endl”vs“\ n”](http://stackoverflow.com/questions/213907/c-stdendl-vs-n)将会是一个很好的阅读。 – 2012-01-31 06:57:38