zoukankan      html  css  js  c++  java
  • 虚拷贝

    当传入对象时,函数有时会需要拷贝该对象并存入容器中,例如:

    类定义:

     1 class Quote {  
     2 public:  
     3     Quote() = default;  
     4     Quote (const std::string& book, double sales_price) :  
     5         bookNo (book), price (sales_price) {}  
     6     void add_item (const Quote& sale);  
     7     std::string isbn() const { return bookNo; }  
     8     virtual double net_price (std::size_t n) const { return n* price; } //虚函数  
     9     virtual Quote* clone() const & {return new Quote(*this);}  
    10     virtual Quote* clone() && {return new Quote(std::move(*this));}  
    11     virtual ~Quote() = default; //动态绑定析构器  
    12 private:  
    13     std::string bookNo;  
    14 protected: //受保护类型  
    15     double price = 0.0;  
    16 };  
    17   
    18 class Disc_quote : public Quote { //抽象基类  
    19 public:  
    20     Disc_quote() = default;  
    21     Disc_quote (const std::string& book, double price, std::size_t qty, double disc) :  
    22         Quote(book, price), quantity (qty), discount (disc) {}  
    23     double net_price (std::size_t) const = 0; //纯虚函数  
    24 protected:  
    25         std::size_t quantity = 0;  
    26         double discount = 0.0;  
    27 };  
    28   
    29 class Bulk_quote final : public Disc_quote { //final限定词, 无法被继承  
    30 public:  
    31     Bulk_quote() = default;  
    32     Bulk_quote(const std::string& book, double p, std::size_t qty, double disc) :  
    33         Disc_quote(book, p, qty, disc) {} //使用基类的构造器  
    34     double net_price(std::size_t cnt) const override;  
    35     virtual Bulk_quote* clone() const & {return new Bulk_quote(*this);}  
    36     virtual Bulk_quote* clone() && {return new Bulk_quote(std::move(*this));}  
    37 };  

    函数定义:

    1 void add_item(const Quote& sale);   //拷贝给定的对象
    2 void add_item(Quote&& sale);         //移动给定的对象

    然而此时,add_item并不知道要分配的类型。当add_item进行内存分配时,它将拷贝sale参数,如

    new Quote(sale)

    然而这条表达式却可能是不正确的:new为我们请求的类型分配内存,因此它将分配一个Quote类型的对象并拷贝sale的Quote部分,然而sale实际指向的可能是Bulk_quote对象,此时add_item所拷贝的对象将失去一部分信息。

    为了解决该问题,我们给Quote类添加了一个虚函数,该函数将申请一份当前对象的拷贝。

     1 class Quote {
     2 public:
     3     virtual Quote* clone() const & { return new Quote(*this); }
     4     virtual Quote* clone() && {return new Quote(std::move(*this)); }
     5 };
     6 class Bulk_quote final : public Disc_quote { 
     7 public:
     8     virtual Bulk_quote* clone() const & { return new Bulk_quote(*this); }
     9     virtual Bulk_quote* clone() && {return new Bulk_quote(std::move(*this)); }
    10 };

    这样每个clone函数分配当前类型的一个新对象,其中,const左值引用成员将它自己拷贝给新分配的对象;右值引用成员则将自己移动到新数据中。

    这样,我们可以使用clone写出新版本的add_item:

     1 void add_item (const Quote& sale)  
     2     {  
     3         //items.insert(std::shared_ptr<Quote>(new Quote(sale))); //不会动态绑定  
     4         items.insert(std::shared_ptr<Quote>(sale.clone()));  
     5     }  
     6     void add_item (Quote&& sale)  
     7     {  
     8         //items.insert(std::shared_ptr<Quote>(new Quote(std::move(sale)))); //不会动态绑定  
     9         items.insert(std::shared_ptr<Quote>(std::move(sale).clone()));  
    10     }  
  • 相关阅读:
    Treap 树堆 容易实现的平衡树
    (转)Maven实战(二)构建简单Maven项目
    (转)Maven实战(一)安装与配置
    根据请求头跳转判断Android&iOS
    (转)苹果消息推送服务器 php 证书生成
    (转)How to renew your Apple Push Notification Push SSL Certificate
    (转)How to build an Apple Push Notification provider server (tutorial)
    (转)pem, cer, p12 and the pains of iOS Push Notifications encryption
    (转)Apple Push Notification Services in iOS 6 Tutorial: Part 2/2
    (转)Apple Push Notification Services in iOS 6 Tutorial: Part 1/2
  • 原文地址:https://www.cnblogs.com/zl1991/p/8484813.html
Copyright © 2011-2022 走看看