简体   繁体   English

C ++重载<<运算符问题

[英]C++ Overloading << Operator problem

I'm fairly noobish at C++, but very comfortable with pointers, dereferencing, etc. I'm having a problem with my overload of the << operator for a class, in that it compiles fine but crashes when run. 我对C ++不太满意,但是对指针,解引用等非常满意。对于类的<<运算符的重载,我遇到了问题,因为它可以很好地编译,但是在运行时会崩溃。 It feels like an infinite loop, but I'm not certain. 感觉就像一个无限循环,但我不确定。 Here's the code, and any help is appreciated. 这是代码,感谢您的帮助。

#include <string>
#include <iostream>

using namespace std;

class Person
{

private:

 string _name;
 Person* _manager;

public:

 Person(string name, Person *manager);
 Person(string name);

 friend ostream &operator<<(ostream &stream, Person &p);

};


Person::Person(string name, Person *manager)
{
 _name = name;
 _manager = manager;
}

Person::Person(string name)
{
 _name = name;
}

ostream &operator<<(ostream &stream, Person &p)
{
 Person* mgr = p._manager;

 stream << p._name << std::endl;
 stream << mgr->_name << std::endl;
 return stream;
}


int main()
{
 Person *pEmployee = new Person("John Doe Employee");
 Person *pManager = new Person("John Doe Manager", pEmployee);

 cout << *pEmployee;
 cout << *pManager;

 return 0;
}

In your constructor with just a single argument, you need to set _manager to NULL/0. 在只有一个参数的构造函数中,您需要将_manager设置为NULL / 0。 Test for this in your operator<< and don't output mgr->name if it is NULL/0. 在运算符<<中对此进行测试,如果为NULL / 0,则不输出mgr-> name。 As it stands, you are dereferencing an uninitialised pointer. 就目前而言,您正在取消引用未初始化的指针。

Person::Person(string name)
{
    _name = name;
    _manager = 0;
}

ostream &operator<<(ostream &stream, Person &p)
{
    Person* mgr = p._manager;

    stream << p._name << std::endl;
    if (mgr)
        stream << mgr->_name << std::endl;
    return stream;
}

There are a number of other things you could do better, such as using const references on arguments and using the constructor initialiser list, but they wont be the cause of your problem. 您还有许多其他可以做的更好的事情,例如对参数使用const引用和使用构造函数初始化程序列表,但这不会成为问题的起因。 You should also address ownership issues with the manager object you pass in to the constructor to ensure it does not get double-deleted. 您还应该使用传递给构造函数的manager对象来解决所有权问题,以确保不会重复删除该对象。

your _manager pointer is not initialized upon constructing the first Person instance, hence referencing p._manager in your operator << crashes. 您的_manager指针在构造第一个Person实例时未初始化,因此在运算符<<中引用p._manager会崩溃。 Besides that, you have a memory leak since you call new but not delete. 除此之外,由于调用了new而不是delete,因此内存泄漏。

Your implementation of operator<< does not check if the _manager member is valid. 您对operator<<实现不会检查_manager成员是否有效。 If there is no manager, you should make this explicit by setting the pointer to 0 . 如果没有管理器,则应通过将指针设置为0来使其明确。 Otherwise the pointer value is undefined and accessing it will crash your program. 否则,指针值是不确定的,访问它会使程序崩溃。

(1) Your Person class should set _manager to 0 (null pointer) if none is supplied in the constructor: (1)如果构造函数中未提供_manager ,则您的Person类应将_manager设置为0 (空指针):

Person::Person(string name) : _name(name), _manager(0)
{
}

(2) In your operator<< , check the pointer before dereferencing it: (2)在operator<< ,在取消引用指针之前检查它:

if (mgr) {
    stream << mgr->_name << std::endl;
}

Some hints for better code: 一些更好的代码提示:

(1) Change your function arguments to accept const string& instead of string . (1)更改函数参数以接受const string&而不是string This way, the string is not copied when calling the function/constructor, but passed as a constant reference. 这样,在调用函数/构造函数时不会复制字符串,而是将其作为常量引用传递。

(2) It is cleaner to let your operator<< accept a const reference for the Person as well, since it does not/should not modify the Person . (2)让operator<<接受Personconst引用是更清洁的做法,因为它不会/不应修改Person This way, you can use the operator also in places where you have a constant Person . 这样,您也可以在具有恒定Person地方使用运算符。

Person::Person(string name)
{
    _name = name;
}

Who is your manager? 你的经理是谁?

Person::Person(string name) : _manager(NULL)
{
    _name = name;
}

ostream &operator<<(ostream &stream, Person &p)
{
 Person* mgr = p._manager;

 stream << p._name << std::endl;
 if (mgr != NULL) { stream << mgr->_name << std::endl; }
 return stream;
}

Your Person instance *pEmployee does not have the _manager set. 您的Person实例* pEmployee没有设置_manager。 This may be a NULL pointer. 这可能是NULL指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM