c++拷贝构造函数与拷贝赋值运算符练习2

参考资料:《C++ Primer习题集(第5版)》

目的:如何让一个类“行为像值”。

/*
 * HasPtr.cpp
 *
 *  
 */
#include 
#include 
using namespace std;

class HasPtr {
private:
    string *ps;
    int i;
public:
    HasPtr(const string &s = string()): ps(new string(s)), i(0) {}//动态内存分配;
    HasPtr(const HasPtr &p) : ps(new string(*p.ps)), i(p.i) {}//拷贝构造函数, *p.ps 表明是p.ps指针所指向的值;
    HasPtr& operator = (const HasPtr &);//拷贝赋值运算符;//类内声明;
    HasPtr& operator = (const string &);//赋予新string;
    string& operator * ();//解引用;
    ~HasPtr();//析构函数;
};
//类外定义;
HasPtr:: ~HasPtr() {
    delete ps;//释放string内存, 将调用string的析构函数;
}

inline//内联函数;
HasPtr& HasPtr:: operator = (const HasPtr &rhs) {
    string *newps2 = new string(*rhs.ps);//拷贝指针指向的对象;
    delete ps;//销毁原string;
    ps = newps2;//指向新string;
    i = rhs.i;//使用内置的int赋值;
    return *this;//返回一个此对象的引用;
}

HasPtr& HasPtr:: operator = (const string &rhs) {
    *ps = rhs;//ps指向的值赋值为rhs;
    return *this;//返回一个此对象的引用;
}

string& HasPtr:: operator * () {
    return *ps;//返回ps的解引用;
}

int main(int argc, char **argv) {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    HasPtr h("hi mom!");
    HasPtr h2(h);//行为类值, h2, h3, h指向不同的string;
    HasPtr h3 = h;//调用拷贝构造函数;

    h2 = "hi dad!";
    h3 = "hi son!";

    cout << "h: " << *h << endl;
    cout << "h2: " << *h2 << endl;
    cout << "h3: " << *h3 << endl;
    return 0;
}
//如果未定义析构函数, 在销毁HasPtr对象时合成的析构函数不会释放指针ps, 造成内存泄漏;
//如果未定义拷贝构造函数, 在拷贝HasPtr对象时, 合成的拷贝构造函数会简单复制ps成员, 使得两个HasPtr指向相同的string;
//当其中一个HasPtr修改string内容时, 另一个HasPtr也被改变;
//如果同时定义了析构函数, 当销毁其中一个HasPtr时, ps指向的string被销毁, 另一个HasPtr的ps成为空指针;
/*
h: hi mom!
h2: hi dad!
h3: hi son!
*/

你可能感兴趣的:(c++拷贝构造函数与拷贝赋值运算符练习2)