类的复制控制

来源:互联网 发布:软件性能测试 编辑:程序博客网 时间:2024/04/29 21:23

复制构造函数还以Sales_item类为例,
在声明与定义Sales_item()函数时,须重载此函数,Sales_item(const Sales_item&);
 最终表现为 Sales_item item1; Sales_item item2(item1); 假如重载了赋值构造函数,则可以对象直

接复制,形如 item1=item2;

在类内声明,重载
Sales_item(const Sales_item&);

类外定义:
Sales_item::Sales_item(const Sales_item& item)
{
    isbn==item.isbn;
    units_sold=item.units_sold;
    revenue=item.revenue;
   return *this;
}

这是类成员中没有指针成员的复制构造函数,假若存在指针型的成员,则另当别论。复制构造函数对于

一个类来说并不是必须的,假如真的有数据成员是指针型的,必须注意其复制形式,否则容易出错

 

类的成员数据假如含有指针类型的成员数据,能不定义复制构造函数就不定义,假如程序需要,等会再写这个。下边先写复制构造函数的详细细节:

复制构造函数可由编译器自动合成,假如显式定义了默认构造函数则不会调用默认合成的复制构造函数,

显式定义复制构造函数时,其形参类型是本类类型的引用,常用const修饰,且必须为本类的引用。

 

对象初始化形式:

string null_book=“999-99-9-999”; 这种方式,创建临时对象,在调用复制构造函数将临时对象复制给null_book;

string dots(10,'.');     直接初始化

string empty_copy=string(); 复制初始化

string empty_direct; 直接初始化

复制初始化时,都隐含了调用复制构造函数,这对某些类来说是很危险的。而且,这四个例子,中第一个和第三个调用operator=();

假若复制构造函数为私有的或者为explicit,则上述定义将是不允许的。

 返回值类型

经常返回类的引用,已传址的方式。

复制控制:

    有些类需要完全禁止复制,例如,iostream 类就不允许复制。想要禁止复制,可以只声明,但不定义。或者将复制构造函数设为私有的成员函数。

大多数类应定义复制构造函数和默认构造函数。如果定义了复制构造函数,也必须定义默认构造函数。。

Sales_item& Sales_item::operator=(const Sales_item& item)

{

    isbn=item.isbn;

    units_sold=item.units_sold;

    revenue=item.revenue;

    return *this;

}

复制构造函数与赋值常一起使用;当然Sales_item中没有指针类型,假若类中含有指针类型,则必须对指针类型进行复制控制!

类指针成员管理:

    设计具有指针成员的类时,类设计者首先需要决定的是该指针应提供声明行为。将一个指针复制到另一个指针时,两个指针指向同一个对象。这时两个指针指向同一个对象,当用一个指针修改该值甚至将该值删除时,而另一个指向此数据的指针却不知道,有可能出现垂悬指针,造成内存泄露。。,采用不同的复制控制策略,可以为指针成员实现不同的行为。

    1、指针成员采取常规指针型行为,这样的类具有指针的所有缺陷但无需特殊的复制控制。

    2、类可以实现所谓的“智能指针”行为,指针多指向的对象是共享的,但类能够防止悬垂指针。

    3、类采取值型行为,分别实现管理指针成员的三种不同方法。

   1的方法是有点不复责任的类。。。。。。。

   2的方法是将指针智能化,却对有些类来说不是必要的。。。。。。。。

   3的方法比较简单易懂,能解决一些结构不是很复杂类的指针成员管理。。。。。。。。

class HasPtr

{

    public:

          HasPtr(int *p,int i):ptr(p),val(i)

       {  }

//此处省略N个字

    private:

        int *ptr;

       int val;

};

在指针复制中,假若采用第三种方法,则必须为指针变量开辟新的地址空间,

HasPtr::HasPtr(const HasPtr& temp)

{

    ptr=new int (*temp.ptr);//此处完全开辟新的空间,不仅仅复制指针,同时也复制指针指向的数据。

    val=temp.val;

};

智能指针
   1.使用引用计数,每复制一次指针成员,智能指针类讲一个计数器与类指向的对象关联。使用计数跟踪该类有多少个对象共享同一指针。使用计数为零时删除对象。
   每次创建类的新对象时,初始化指针并将使用计数致一。当对象作为另一对象的副本而创建时,复制构造函数复制指针并增加与之相应的使用计数的值。对一个对象进行赋值时,赋值操作符减少左操作数所指对象的使用计数的值,并增加右操作数多指对象的使用计数的值。最后,调用析构函数时,析构函数减少使用计数的值,如果计数减致0,则删除基础对象。唯一的创新,决定于使用计数放在哪里。计数器不能直接放在HasPtr对象中。
    class U_Ptr
{
    friend class HasPtr;
    int *ip;
    size_t use;
    U_Ptr(int* p):ip(p),use(1){}
    ~U_Ptr() { delete ip; }
};
class HasPtr
{
    public:
     HasPtr(int* p,int i):ptr(new U_Ptr(p)),val(i){}
     HasPtr(const HasPtr &orig):ptr(orig.ptr),val(orig.val){ ++ptr->use; }
     HasPtr& operator=(const HasPtr);
     ~HasPtr(){if(--ptr->use==0) delete ptr;}
    private:
      U_Ptr *ptr;
      int val;
};
HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
    ++rhs.ptr->use;
    if(--ptr->use==0)
         delete ptr;
    ptr=rhs.ptr;
    val=rhs.val;
   return *this;
}
以上是一种智能指针使用的例子

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 西服裤子太长了怎么办 苹果主板被偷怎么办 乐视手机漏电怎么办 店铺承租方得不到补偿怎么办? 淘宝空间满了怎么办 微销通登录不上怎么办 淘宝宝贝被监控怎么办 邮政快递不派送怎么办 快递员不接电话怎么办 小米电视不发货怎么办 门禁卡没有磁性怎么办 食堂卡没有磁性怎么办 市民卡没有磁性怎么办 手机拍视频反光怎么办 摄影师接不到单子怎么办 淘宝七天没发货怎么办 淘宝商家漏发货怎么办 毒app虚假发货怎么办 淘宝店拒绝发货怎么办 买东西不给发票怎么办 淘宝店不想发货怎么办 淘宝商品不发货怎么办 买家恶意不退款怎么办 手机淘宝不发货怎么办 闲鱼虚假发货怎么办 买假货没发票怎么办 淘宝发票丢了怎么办 淘宝卖家不给发票怎么办 淘宝如果不要发票怎么办 闲鱼没有发票怎么办 淘宝店没有发票怎么办 物流不提供发票怎么办 电子发票重复报销怎么办 鬼火摩托车没电怎么办 摩托粘了缸怎么办 摩托淹缸了怎么办? 晚上睡不着早上睡不醒怎么办 三唑仑吃了以后难受怎么办 吃两片三唑仑第二天头晕怎么办 买家收货不付钱怎么办 淘宝上买东西被骗怎么办