C++面向对象入门(二十四)重载赋值运算符
为什么要重载赋值运算符?
在用户定义类后, 编译器会默认提供无参构造(空实现), 析构(空实现), 拷贝构造(值拷贝), 重载赋值运算符(值赋值)
但是若类成员属性为指针变量时, 编译器提供的重载赋值运算符只会简单的把指针变量的值赋值, 而不会申请一份新的内存空间, 将指针指向的变量赋值给这片内存空间,
当我们在析构中释放内存时, 就会出现一段的内存被重复释放的情况, 从而导致程序运行出错. 故需要自己给出重载赋值运算符函数
示例代码:
#include <iostream> #include <string> using namespace std; /** * recipe n.秘诀;处方;食谱; * 为什么要重载赋值运算符? *在用户定义类后, 编译器会默认提供无参构造(空实现), 析构(空实现), 拷贝构造(值拷贝), 重载赋值运算符(值赋值) *但是若类成员属性为指针变量时, 编译器提供的重载赋值运算符只会简单的把指针变量的值赋值, 而不会申请一份新的内存空间, 将指针指向的变量赋值给这片内存空间, *当我们在析构中释放内存时, 就会出现一段的内存被重复释放的情况, 从而导致程序运行出错. 故需要自己给出重载赋值运算符函数 * 语法: * 类名 &operator=(const 类名 &变量名) * { * 函数体 * } * 注意事项: * 1, 对于这种含有指针类型的成员变量的类, 其构造函数中应该都有申请内存空间的语法 * 因此不需要再重载赋值运算符函数中再申请内存 * 2, 函数返回值类型应该引用类型, 返回值为调用对象的的引用(使用*this指针返回) */ const int MAXSIZE = 100; double abs(double a) { if(a < 0) return -a; return a; } class Item { string name; double price; int quantity; public: Item() { } Item(const string &name, double price, int quantity) : name(name), price(price), quantity(quantity) {} }; struct Goods { string name; double price; string getInfo() { return "name: " + name + ", price: " + to_string(price); } }; ostream &operator<<(ostream &cout, const Goods &goods); class Store { friend ostream &operator<<(ostream &cout, const Store &store); private: double balance; Item *itemList; Goods *menu; int goodsQuantity; public: const string name = "MINI STORE"; Store() : balance(0),goodsQuantity(0) { this->itemList = new Item[MAXSIZE]; this->menu = new Goods[MAXSIZE]; } Store(double balance, Item *itemList, Goods *menu, int goodsQuantity) : balance(balance), goodsQuantity(goodsQuantity) { this->itemList = new Item[MAXSIZE]; this->menu = new Goods[MAXSIZE]; for (int i = 0; i < goodsQuantity; ++i) { this->itemList[i] = itemList[i]; this->menu[i] = menu[i]; } } ~Store() { cout << "Close the Store" << endl; } Store &operator=(const Store &store) { balance = store.balance; goodsQuantity = store.goodsQuantity; for (int i = 0; i < goodsQuantity; ++i) { this->itemList[i] = store.itemList[i]; this->menu[i] = (store.menu)[i]; } return *this; } }; ostream &operator<<(ostream &cout, const Goods &goods) { cout << "name:" << goods.name << ", price:" << goods.price; return cout; } ostream &operator<<(ostream &cout, const Store &store) { cout << "name:" << store.name << endl; cout << "MENU:" << endl; for (int i = 0; i < store.goodsQuantity; ++i) { if(abs(store.menu[i].price-0) > 1e-6) cout << store.menu[i] << endl; } cout << "balance:" << store.balance << endl; return cout; } void test1() { Item itemList[] = {Item("apple", 2.5, 10), Item("watermelon", 1.2, 100), Item("grape", 10, 15)}; Goods menu[] = {Goods{"apple", 2.5}, Goods{"watermelon", 1.2}, Goods{"grape", 10}}; Store store = {100, itemList, menu, 3}; Store s2; cout << "Before assign, the object s2 is :" << endl; cout << s2; s2 = store; cout << "After assign, the object s2 is :" << endl; cout << s2; } int main() { test1(); system("pause"); return 0; }
路漫漫其修远兮,吾将上下而求索。