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

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

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