zoukankan      html  css  js  c++  java
  • C++进阶--拥有资源句柄的类(浅拷贝,深拷贝,虚构造函数)

    // Person通过指针拥有string
    class Person {
    public:
       Person(string name) { pName_ = new string(name); }
       ~Person() { delete pName_; }
    
       void printName() { cout << *pName_; }
    
    private:
       string* pName_;
    };
    
    int main() {
       
       vector<Person> persons;
       persons.push_back(Person("George")); 
    
       persons.front().printName(); //这里会崩
    
       cout << "Goodbye" << endl;
    }
    
       //persons.push_back(Person("George")); 事实上该行代码可以分解成以下步骤
       // 1. "George" 被构造
       // 2. "George"的一个副本保存到(浅拷贝)
       // 3. "George"被销毁
    
    // Solution 1: 定义拷贝构造和拷贝赋值实现深拷贝
    	Person(const Person& rhs) {   
          pName_ = new string(*(rhs.pName()));
       }
    	Person& operator=(const Person& rhs);  
       string* pName() const { return pName_; }
    
    // Solution 2: 禁用拷贝构造和拷贝赋值
    // 对C++ 11,使用=delete
    // for C++ 03, 声明但不定义
    	Person(const Person& rhs); 
    	Person& operator=(const Person& rhs);  
    
    // 如果禁用之后仍然需要拷贝,使用clone()
    // 显式的拷贝
    	Person* clone() {  
          return (new Person(*(pName_)));
       }
    
    // 更推荐方法2:
    // 1. 因为拷贝构造和拷贝赋值经常并不需要
    // 2. 使拷贝显式,隐式拷贝容易出现bug
    // 3. clone可以利用多态实现虚构造函数,自动根据指针所指对象的类型拷贝基类或者派生类对象
    
    class Dog { 
    public:
       virtual Dog* clone() { return (new Dog(*this)); }   //co-variant return type 允许覆写函数具有不同的返回类型,只要返回类型由基类的返回类型派生得到
    };
    
    class Yellowdog : public Dog { 
       virtual Yellowdog* clone() { return (new Yellowdog(*this)); }
    };
    
    void foo(Dog* d) {      // d 是Yellowdog
       //Dog* c = new Dog(*d); // c 是Dog,不是我们想要的
       Dog* c = d->clone();    // c是Yellowdog
       //... 
       //
    }
    
    int main() {
       Yellowdog d;
       foo(&d);
    }
    
    // C++ 11 的方法:
    //    shared_ptr<string> pName_;
    //    大多数情况下用unique_ptr也可以, 但是跟STL container一起使用时必须使用shared_ptr, 
    //    因为STL容易要求元素时可拷贝的
    
  • 相关阅读:
    win10下安装Oracle 11g 32位客户端遇到INS-13001环境不满足最低要求
    kubernetes环境下私有仓库搭建
    Build a Restful Service
    大数据的开始:安装hadoop
    调试Ajax调用的利器firebug
    Oracle Process Cloud流程云实践
    Kubernetes环境下如何运行Coherence缓存集群
    Kubernetes的负载均衡问题(Nginx Ingress)
    Kubernetes master节点的高可用配置
    Kubernetes环境下调整WebLogic JVM基本参数
  • 原文地址:https://www.cnblogs.com/logchen/p/10166653.html
Copyright © 2011-2022 走看看