【问题标题】:Operator overloading segmentation fault运算符重载分段错误
【发布时间】:2013-04-26 18:40:04
【问题描述】:

我正在创建一个函数,当我的 Student 类中的两个对象被重载时,它会重载 + 运算符。该函数应该添加他们的年龄和身高(类的两个受保护的数据字段)。然后它调用构造函数来创建一个具有这些字段的新学生。这也是模板中的练习,因此无法删除这些字段。

当我编译我的程序时,我在运行时遇到了分段错误。使用 cout 语句,我可以看到正在创建新的 Student 并且退出了构造函数,但是随后发生了分段错误。我意识到这一定是内存问题,但我无法找到解决方案。我曾尝试使用动态内存在重载运算符和主函数中创建新学生,但错误仍然存​​在。

这里是构造函数:

template <typename T>
Student<T>::Student(int age, int height)
{
    this->age = age;
    this->height = height;

    cout << "New student created"<< endl;
    return;
}  

这里是重载的操作符函数:

template<typename T>
Student<T> Student<T>::operator+(Student<T> &secondStudent) const
{
    int a = age + secondStudent.getAge();
    int h = height + secondStudent.getHeight();

    new Student(a, h);
}

这里是主要功能:

Student<int> *s2 = new Student<int>(15, 63);
Student<int> *s3 = new Student<int>(18, 72);

Student <int> s4 = (*s2+ *s3);
cout << "did it return?" << endl;

注意,两个cout语句是打印的,所以我知道调用了操作符,创建了student,但是后来遇到了内存问题。

【问题讨论】:

  • 打开编译器的警告。另请注意,您几乎不应该在 C++ 中使用 new 和 delete,更不用说一旦 make_unique 到达。
  • 不是你问的,但放弃指针Student&lt;int&gt; s2(15, 63); Student&lt;int&gt; s3(18, 72); Student&lt;int&gt; s4 = s2 + s3;。没有它们,编程会容易得多。
  • 您似乎很难将编程实践从 Java 音译为 C++。在 C++ 中,您应该很少使用 new 关键字。

标签: c++


【解决方案1】:

您的 operator + 重载不会返回任何内容(您没有 return 语句),因此您会遇到未定义的行为(导致分段错误的原因)。此外,您的operator + 函数会因为忽略new 的返回值而无缘无故地导致内存泄漏。甚至没有理由在这里使用new。你想说:

template<typename T>
Student<T> Student<T>::operator+(Student<T> &secondStudent) const
{
    int a = age + secondStudent.getAge();
    int h = height + secondStudent.getHeight();

    return Student(a, h);
}

你不需要在 C++ 中使用 new 关键字,除非你有特定的理由在堆上分配一些东西。 (new 返回一个指向动态分配对象的 指针。)在您的情况下,您只想创建并返回一个 Student 对象。

【讨论】:

  • 啊,谢谢...。我在所有模板标签中迷失了方向,暂时忘记了函数应该指定它们返回的内容...
【解决方案2】:

问题出在这里:

template<typename T>
Student<T> Student<T>::operator+(Student<T> &secondStudent) const
{
    int a = age + secondStudent.getAge();
    int h = height + secondStudent.getHeight();

    new Student(a, h);
//  ^^^^^^^^^^^^^^^^^^
}

您正在动态创建一个对象,但您的函数中没有return 语句。这是未定义的行为(此外,您还泄漏了该对象,因为没有对 delete 的相应调用)。相反,你可以写:

template<typename T>
Student<T> Student<T>::operator+(Student<T> &secondStudent) const
{
    int a = age + secondStudent.getAge();
    int h = height + secondStudent.getHeight();

    return Student(a, h);
//  ^^^^^^^^^^^^^^^^^^^^^
}

请注意,通过原始指针newdelete 进行手动内存管理通常是个坏主意。如果您确实需要引用语义,请考虑使用智能指针。

【讨论】:

    猜你喜欢
    • 2013-11-21
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    相关资源
    最近更新 更多