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容易要求元素时可拷贝的
    
  • 相关阅读:
    973. K Closest Points to Origin
    919. Complete Binary Tree Inserter
    993. Cousins in Binary Tree
    20. Valid Parentheses
    141. Linked List Cycle
    912. Sort an Array
    各种排序方法总结
    509. Fibonacci Number
    374. Guess Number Higher or Lower
    238. Product of Array Except Self java solutions
  • 原文地址:https://www.cnblogs.com/logchen/p/10166653.html
Copyright © 2011-2022 走看看