复制控制

复制构造函数,赋值操作符,析构函数总称为赋值控制。编译器自动实现这些操作,但类设计者也可以定义自己的版本。类具有指针成员时,类必须定义自己的复制控制成员。
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;
};

猜你喜欢

转载自blog.csdn.net/c1204611687/article/details/73618022
今日推荐