【问题标题】:Error in C++ code when overloading operators重载运算符时 C++ 代码中的错误
【发布时间】:2012-12-25 20:23:05
【问题描述】:

我试图在我的代码中重载“+”和“=”运算符,但我不断收到运行时错误,并且程序在使用 VS2012 运行时崩溃,但在 borland C 3.1 中运行完美。

这是我的代码:

class employee{
    int eid;
    long esalary;
    char * ename;
    static char company_name[20];
    static int emp_count;

    public:

    static char * getcompanyname(){
        return company_name;
    }
    static int getempcount(){
        return emp_count;
    }
    void set(int empid);
    void set(long empsalary);
    void set(char empname[]);
    int getid();
    long getsalary();
    char * getname();
    employee(int empid=0,long empsalary=0,char empname[]="NA"){
        eid=empid;
        esalary=empsalary;
        ename=new char[strlen(empname)+1];
        strcpy(ename,empname);
        emp_count++;
    }

    employee(employee &ref){
        eid=ref.eid;
        esalary=ref.esalary;
        ename=new char(strlen(ref.ename)+1);
        strcpy(ename,ref.ename);
    }

    ~employee(){
        delete(ename);
    }

    employee operator+(employee &ref){
        employee temp(*this);
        temp.esalary=esalary+ref.esalary;
        return(temp);
    }
    employee& operator= (employee &ref){
        eid=ref.eid;
        esalary=ref.esalary;
        return * this;
    }

}e1,e2,emp;

然后在主目录中:

emp=e1+e2;

【问题讨论】:

  • 请发布 VS2012 的运行时错误信息。另请考虑修改问题的标题,以更具体的方式反映问题的内容。
  • 你是否在课堂上重载了它们?最后一行是在哪里制作的?
  • PS:实现是在类中定义的……最后一行在主函数中
  • operator[] 是怎么过载的?
  • 如果你给我们看更多的代码——例如,e[] 是从哪里来的? Borland C,你在 DOS 下运行吗?在这种情况下,您可能不会崩溃,如果您超出分配的内存,只会出现奇怪的行为。如果 e[] 有 3 个元素,则 e[3] 无效!

标签: c++ class operator-overloading operator-keyword


【解决方案1】:

说实话,您的代码无效。它甚至不应该编译,因为它违反了引用绑定规则:+ 运算符返回一个临时对象,它不能通过非 const 引用传递给 = 运算符。如果您设法编译了此代码,则仅意味着您的编译器接受它作为语言的“扩展”。

要修复该特定错误,您必须在声明中添加一堆 const 限定符

employee operator +(const employee &ref) const {
  employee temp(*this);
  temp.esalary = esalary + ref.esalary;
  return temp;
}

employee& operator =(const employee &ref){
  eid = ref.eid;
  esalary = ref.esalary;
  return *this;
}

这将使您的代码从 C++ 的角度来看有效,但它可能无法修复崩溃,因为崩溃的原因必须在其他地方。


这是导致崩溃的错误:在复制构造函数中您执行了此操作

ename=new char(strlen(ref.ename)+1);

当你用new分配一个数组时,你必须使用[]括号,而不是()

ename = new char[strlen(ref.ename) + 1];

您在第一个构造函数中正确执行了此操作,但由于某种原因,您在复制构造函数中使用了() 而不是[]() 在这种情况下意味着完全不同的东西:它分配一个 char 并将其初始化为 strlen(ref.ename) + 1 值。

顺便说一句,您没有在复制赋值运算符中复制ename 的原因是什么?

此外,使用new[] 分配的内存必须使用delete[] 释放。不是delete,而是delete[]。你的析构函数应该是这样的

~employee() {
  delete[] ename;
}

最后,您最好使用std::string 存储ename,而不是依赖原始内存管理。 (除非您被明确要求这样做)。

【讨论】:

  • 我正在复制 ename,但后来我删除了它,因为我认为它是错误源……抱歉,std::string 是什么?
  • @Mazen:std::string是C++标准库提供的一个类。它旨在存储字符串值。它负责内部的所有内存管理,因此您不必自己动手。
猜你喜欢
  • 2018-03-14
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多