【问题标题】:Overloading ostream << operator returning address重载 ostream << 运算符返回地址
【发布时间】:2015-01-25 22:19:20
【问题描述】:

我正在制作一个简单的 Person 类,它派生自 Object。 每个人都有一个名字 (char*)。 我希望能够打印使用 cout 的人的姓名。 我没有达到预期的结果。 这是我的代码:

人.h

#include <iostream>
#include <cstring>
#ifndef _PERSON_H_
#define _PERSON_H_
using namespace std;

class Object {};

class Person : public Object {
private:
    char* m_name;


public:
    Person(char* input);
    ~Person();
    char* getName() const;
    //Set to friend because otherwise I was getting a compilation error.
    friend ostream& operator<<(ostream& os, const Person& p);
};



#endif // _PERSON_H_

Person.cc

#include "Person.h"
#include <iostream>
#include <cstring>

Person::Person(char* input) {
    m_name = new char[strlen(input)];
    strncpy(m_name, input, strlen(input));
}

char* Person::getName() const{
    return m_name;
}

/*Person& Person::operator=(const Person &rhs) {
    delete [] m_name;
    m_name = new char[strlen(rhs.getName())];
    strncpy(m_name, rhs.getName(), strlen(rhs.getName()));
    return *this;
}*/

ostream& operator<<(ostream& os, const Person& p) {
    os << p.getName();
    return os;
}

Person::~Person() {}

int main() {
    char* tmp = "dave";
    Person * p = new Person(tmp);
    cout<<p;
}

使用上面的代码输出:

0x7fbba3c04b60

如果我将 main 的最后一行更改为:

cout<<*p

我得到了想要的结果,即 dave

我的参考资料: Microsoft Developer Network

如何让cout&lt;&lt;p 打印dave

【问题讨论】:

    标签: c++ operator-overloading ostream


    【解决方案1】:

    std::ostream&amp; operator&lt;&lt; 有一个以十六进制格式打印地址的指针的重载(除非它们是指向字符类型的指针,在这种情况下它假定一个以空值结尾的字符串。)当你说时调用该重载

    cout<<p;
    

    因为p 是一个指针。您可以使用其他指针对此进行测试:

    int i = 0;
    int* pi = &i;
    double d = 3.14;
    double* pd = &d;
    
    cout << pi << ", " << pd << '\n';
    

    【讨论】:

    • 谢谢。我通过将重载函数接收到的参数更改为指针来修复它:friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const Person * p);
    • @Airwavezx 你真的不应该那样做。你应该让指针作为指针打印出来。
    • 我编辑了该行,它应该是*p 而不仅仅是p。可以吗?
    • 不,你真的不应该那样做。你应该让指针作为指针打印出来。
    【解决方案2】:

    如果你想让你的对象在这两种情况下都能工作

    cout << p ;
    cout << *p;
    

    您还必须为指针重载运算符,因此您可以将其添加到您的代码中并保留旧的:

    friend ostream& operator<<(ostream& os, const Person* p);
    
    ostream& operator<<(ostream& os, const Person* p) {
        os << p->m_name << "\n";
        return os;
    }
    

    所以你有两个重载的操作符函数

    friend ostream& operator<<(ostream& os, const Person* p)
    

    friend ostream& operator<<(ostream& os, const Person p)
    

    【讨论】:

    • 我就是这么做的。虽然上面有人提到这不是一个好主意。
    • 很抱歉没有看到您的评论。我认为这是解决问题的方法,但这不是最好的主意,但通常如果您将指针作为 const 传递,则可以确保指针已初始化
    【解决方案3】:

    可以operator &lt;&lt; 重载为Person*,但这样做会非常不习惯,并且会让所有其他 C++ 用户感到困惑。

    在 C++ 中正确的做法是不要假装指向对象的指针就是对象。

    【讨论】:

      【解决方案4】:

      您正在实现您想要的结果。只需使用

      cout &lt;&lt; p

      调用重载std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, void*),显示指针p指向的地址。

      cout &lt;&lt; *p

      取消引用指针并调用您的重载。

      【讨论】:

        【解决方案5】:

        您也可以提供一个接受Person* p 的运算符。但典型的实现是在指针前面放一个星号——编译器无论如何都会简单地传递指针,因为调用使用的是引用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-10-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-17
          • 2020-02-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多