第36课.经典问题解析三

1.需要进行深拷贝的时候必须重载赋值操作

重载赋值操作必然需要实现深拷贝

include

include

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()任为空。

注意:不要使用c语言中的方式操作c++中的字符串(即使用指针(char* p)去操作string对象)

posted @ 2019-11-20 15:41  人民广场的二道贩子  阅读(179)  评论(0)    收藏  举报