複製控制

複製構造函數,賦值操作符,析構函數總稱爲賦值控制。編譯器自動實現這些操作,但類設計者也可以定義自己的版本。類具有指針成員時,類必須定義自己的複製控制成員。
1.複製構造函數

只有單個形參,且該形參爲本類類型對象的const引用。複製構造函數的作用有:
根據另一個同類型的對象初始化一個對象
函數形參或返回類型爲類對象時,調用複製構造函數
容器或數字裏是類對象時,調用複製構造函數

class Foo
{
public:
    Foo();
    Foo(const Foo & rhs); //複製構造函數
};

爲了禁止複製構造函數,可以將複製構造函數聲明爲private,且不定義複製構造函數。不允許複製的類對象只用作爲引用傳遞給函數或從函數返回,且不能用作容器的元素。
2.賦值操作符

class Foo
{
public:
    Foo & operator=(const Foo & rhs);
}

一般的,複製和賦值操作符一起使用,如果一個類需要定義自己的複製構造函數,那它必然需要定義賦值操作符
3.析構函數
3法則,如果需要定義自己的析構函數,則必然需要定義複製構造函數和賦值操作符
合成析構函數並不刪除指針成員所指向的對象,就算定義了自己的析構函數合成析構函數仍然運行。
一般的賦值操作符通常要做析構函數和複製構造函數要做的工作
4.智能指針
一個例子:

class HasPtr
{
public:
    HasPtr(int *p):ptr(p){}
    int * GetPtr()const {return ptr;}
    void SetPtr(int *p){ptr = p;}
    int  GetPtrVal()const {return *ptr;}
    void SetPtrVal(int val)const{*ptr = val;}
    ~HasPtr(void);
private:
    int *ptr;
};

智能指針實現版本

pragma once

class UPtr
{
friend class HasPtr;
size_t count;
int *ptr;
UPtr(int *p):count(1),ptr(p){}
~UPtr(){delete ptr;}
};
class HasPtr
{
public:
HasPtr(int *p):ptr(new UPtr(p)){}
HasPtr(const HasPtr &rhs):ptr(rhs.ptr){++(ptr->count);}
HasPtr & operator=(const HasPtr &rhs)
{
++rhs.ptr->count;
if (–ptr->count == 0)
{
delete ptr;
}
ptr = rhs.ptr;
return *this;
}
~HasPtr()
{
if (–ptr->count == 0)
{
delete ptr;
}
}
private:
UPtr *ptr;
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章