赋值操作符的重载
1. 编译器为每个类的赋值操作符进行了默认的重载。
2. 默认的赋值操作符只有浅拷贝功能。
3. 需要深拷贝是要对默认赋值操作符进行重载。
4. 默认赋值操作符与默认拷贝函数意义相同
#include <iostream> #include <string> using namespace std; class Test { int* m_pointer; public: Test() { m_pointer = NULL; } Test(int i) { m_pointer = new int(i); // 内部指向了外部资源 } Test(const Test& obj) // 重写浅拷贝函数 { m_pointer = new int(*obj.m_pointer); } Test& operator = (const Test& obj) // 重写赋值操作符 { // 1.操作符和返回值是引用,目的是为了在一个表达式中连续使用操作符 if( this != &obj ) // 2.参数是const引用,目的是不改变参数值 { delete m_pointer; // 3.处理自赋值的情况 m_pointer = new int(*obj.m_pointer); } return *this; // 4.返回指向当前对象的指针 } ~Test() { delete m_pointer; } }; int main() { Test t1 = 1; Test t2;
t2 = t1; //调用赋值重载操作符函数。 如果是浅拷贝将会使得Test.m_pointer指向同一片堆空间,delect时发送段错误
return 0; }
编译器为空类提供的默认函数:
1. 默认构造函数
2. 默认拷贝函数
3. 赋值符的默认重载函数
4. 默认析构函数
class Test //自定义空类 { }; class Test //编译器默认添加函数后的类 { public: Test(); Test(const Test& ); Test& operator = (const Test&); ~Test(); };
不可用C++语言写C语言,用面向对象的思想写C++。
#include <iostream> #include <string> using namespace std; int main() { string s = "12345"; const char* p = s.c_str(); // P 和 m_cstr 指向“12345” cout << p << endl; s.append("abced"); // m_cstr 指向“12345adceb” ,字符串缓冲区已变,p 成为了野指针 cout << p << endl; return 0; }
当用C语言操作某些对象后之改变了对象的某一种属性,对于其他属性去没有进行相应的改变。
#include <iostream> #include <string> using namespace std; int main() { const char* p = "12345"; string s = ""; // m_cstr 指向 "",m_lengh 为0。 s.reserve(10) // 不要使用 C 语言中的方式操作 C++ 中的字符串 for(int i=0; i<5; i++) // m_cstr 指向 "12345",m_lengh 依旧为0。 { s[i] = p[i]; // 只改变了string类的 m_cstr 属性,对于 m_lengh 属性却没有改变。 可改为:s = p; } cout << s << endl; //打印为空 return 0; }