1、等号操作符重载,实现深拷贝
//等号运算符重载 // obj3=obj1;//原始的是浅拷贝,现在要重载为深拷贝 Name& operator=(Name &obj1) { //1、先释放旧的内存 if (this->m_p != nullptr) { delete[] m_p; m_len = 0; } //2、根据 obj1 分配内存大小 this->m_len = obj1.m_len; this->m_p = new char[m_len + 1];
//3、把obj1赋值给obj3 strcpy(m_p, obj1.m_p); return *this;//返回引用,实现链式编程 }
2、赋值运算符重载
由于动态申请了堆空间,因此必须重载复制构造函数和赋值运算符:
(1)复制构造函数在创建对象时调用,此时对象还不存在,只需申请空间,不需释放原有的;
(2)赋值运算符在对象已经存在的情况下调用,需要先释放原有对象占用的空间,然后申请新的空间;由于原有空间大小不一定满足现有需求,所以要先释放后申请。
问题:
(1)删除赋值运算符的重载,程序是否正常,为什么?
答:程序可以正常运行,但结束时会出现内存错误,因为 name 所指向的内存被释放了 2 次。 由于自动调用了默认的 等号运算符 ,出现两个对象公用一个内存空间。
class student { public: student(int i = 0, char *c = NULL, float s = 0); student(student& s); student& operator=(student& s); ~student() { delete []name; } void printstu() { cout << "numner: " << id << " name: " << name << " score: "<<score << endl; } private: int id; char* name; float score; }; student::student(int i, char* c, float s) { id = i; score = s; if (c == NULL) { name = nullptr; } else { name = new char[strlen(c) + 1]; strcpy_s(name, strlen(c) + 1, c); } } // 复制构造函数 student::student(student& s) { id = s.id; score = s.score; name= new char[strlen(s.name) + 1]; if (name != 0) strcpy_s(name, strlen(s.name) + 1, s.name); } //重载赋值运算符 student& student::operator=(student& s) { id = s.id; score = s.score; delete[]name; name = new char[strlen(s.name) + 1]; strcpy_s(name, strlen(s.name) + 1, s.name); return *this; } void main() { student s1(1, "wang", 86); s1.printstu();
student s2(s1);//可以在定义时,直接初始化,自动调用复制构造函数 student s3; //因为使用了 等号运算符,所以如果不重载,则会自动调用默认的等号运算。 s3 = s1;
s2.printstu(); system("pause"); }
3、逻辑与和逻辑或,不能运算符重载
&& ,||, 重载他们不会产生短路规则。例子:t1 &&(t2+t3),前面的 t1 不成立,则不会执行后面的语句。