第36课.经典问题解析三
1.需要进行深拷贝的时候必须重载赋值操作
重载赋值操作必然需要实现深拷贝
#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)
{
if(this != &obj)
{
m_pointer = new int(*obj.m_pointer);
}
return *this;
}
void print()
{
cout << "m_pointer = " << m_pointer << endl;
}
~Test()
{
delete m_pointer;
}
};
int main()
{
Test t1(1);
Test t2;
t2 = t1;
t1.print();
t2.print();
return 0;
}
2.关于string的疑问(c和c++混用的bug)
a.下面代码输出什么?为什么?
string s = "12345";
const char* p = s.c_str(); //把这个string类型的对象的指针地址返回
cout << p << endl; //此时p->s的地址。所以cout:12345
s.append("abcd"); //在12345,后插入abcd
cout << p <<endl; //理论上这里应该是12345abcd
显然结果不是我们所想的那样的。
string对象内部维护了一个指向数据的char*指针,这个指针可能在程序运行的过程中发生改变。(这里当我们要在s成员的尾部插不入一段内容时,会重新分配空间,把之前的值和插入的值赋值到这个新空间中。并把之间的空间释放掉。p指针变成了野指针)
b.下面的程序输出什么?为什么?
const char* p = "12345";
string s = "";
s.reserve(10); //分配的堆大小为10
for(int i = 0; i < 5; i++) //把p的值赋给s
{
s[i] = p[i];
}
if(!s.empty()) //如果s不为空打印s
{
cout << s << endl;
}
/* 有输出结果,1,2,3,4,5
for(int i = 0; i < 5; i++)
{
cout << s[i] <<endl;
}
*/
没有结果输出,但是测试了发现s中有内容。证明赋值成功了。那为什么没有输出呢?因为s.empty()为空。empty()为类中的成员函数,我们在改变s中的值的时候没有改变s.empty()。所以对它来说,s.empty()任为空。