重载>>运算符给我运行时错误C ++

时间:2013-06-19 17:00:55

标签: c++ operator-overloading

任何人都可以帮助我。下面是我正在尝试执行的代码。没有编译时错误,但是当控件转到字符串复制语句时程序崩溃。我试图修复它差不多一个小时,但仍然没有成功。

#include <iostream>

using namespace std;

class test
{
      private:
              char* name;
      friend istream& operator >>(istream&, test&);
};

istream& operator >> (istream& is, test& t)
{
          char c[20];

          cout << "enter something";
          is >> c;
          strcpy(t.name, c);
          return is;
}

int main()
{
    test obj;
    cin >> obj;

}

1 个答案:

答案 0 :(得分:7)

name指针在您调用strcpy时未初始化,这会为您的程序提供未定义的行为。

要避免此类问题,请使用std::string而不是C字符串。更具体地说,用这种方式重新定义你的课程:

#include <string> // Needed for std::string

class test
{
private:
    std::string name;
    friend istream& operator >>(istream&, test&);
};

要使程序编译,您可以通过这种方式调整operator >>的重载:

istream& operator >> (istream& is, test& t)
{
    cout << "enter something";
    is >> t.name;
    return is;
}

但请注意,您不应该提示用户提取 in 提取运算符(即在operator >>的重载内)。插入运算符只应从输入流中提取类型为test的对象。

因此,提供一个完整的例子:

#include <iostream>
#include <string>

class test
{
private:
    std::string name;
    friend std::istream& operator >>(std::istream&, test&);
};

std::istream& operator >> (std::istream& is, test& t)
{
    is >> t.name;
    return is;
}

int main()
{
    test obj;
    std::cout << "enter something: ";
    std::cin >> obj;
}

还要避免using指令,例如:

using namespace std;

特别是在命名空间范围内,特别是在标题中(不是你的情况,但仍然) - 它们往往会导致与std命名空间中存在的实体发生名称冲突。


修改

由于您似乎不允许使用std::string,因此只有原始答案的第一句仍然有效 - 以及关于您应该向用户询问输入的部分,也许。

这就是您可以编写的用于分配用户输入的字符串的t.name 副本的内容:

t.name = strdup(c);

您需要为<cstring>添加strdup()标准标头:

#include <cstring>

我还建议在name类的构造函数中将test指针初始化为null - 它不会被隐式生成的默认构造函数初始化:

class test
{
    test() : name(nullptr) { } // Use NULL instead of nullptr in C++03
private:
    char* name;
    friend istream& operator >> (istream&, test&);
};

所以在一个完整的程序中:

#include <iostream>
#include <cstring>

class test
{
public:
    test() : name(nullptr) { }
private:
    char* name;
    friend std::istream& operator >>(std::istream&, test&);
};

std::istream& operator >> (std::istream& is, test& t)
{
    char c[20];
    is >> c;
    t.name = strdup(c);
    return is;
}

int main()
{
    test obj;
    std::cout << "enter something: ";
    std::cin >> obj;
}