c++ - Smart pointer (unique_ptr) instead of raw pointer as class member -


given class hierarchy:

class {  private:   string * p_str;  public:   a() : p_str(new string())   {   }    virtual ~a() {     delete p_str;   } };  class b : public { public:   b() {   }    virtual ~b() override {   }    virtual void test() {     cout << "b::test()" << endl;   } };  int main(int, char**) {   b b;    b.test();      return 0; } 

there p_str pointer string (no matter object points to).

is there advantage of replacing std::unique_ptr except not writing delete p_str?

class {  private:   std::unique_ptr<string> p_str;  public:   a() : p_str(make_unique<string>())   virtual ~a() {}  } 

? if constructor of derived class throws exception, there memory leak occured in variant of code.

upd tried code:

include

#include <memory> using namespace std;  class pointed { public:   pointed() { std::cout << "pointed()\n"; }   ~pointed() { std::cout << "~pointed()\n"; } };  class a1 { private:   pointed * p_str;  public:   a1() : p_str(new pointed()) {     cout << "a1()\n";     throw "a1 constructor";   }    virtual ~a1() {     cout << "~a1()\n";     delete p_str;   } };  class b1 : public a1 { public:   b1() {     throw "b constructor";   }    virtual ~b1() override {     cout << "~b1()\n";   }    virtual void test() {     cout << "b1::test()" << endl;   } };  class a2 { private:   std::unique_ptr<pointed> p_str;  public:   a2() : p_str(make_unique<pointed>()) {     cout << "a2()\n";     throw "a2 constructor";   }    virtual ~a2() {     cout << "~a2()\n";   } };   class b2 : public a2 { public:   b2() {     cout << "b2()\n";     throw "b2 constructor";   }    virtual ~b2() override {     cout << "~b2()\n";   }    virtual void test() {     cout << "b2::test()" << endl;   } };  int main(int, char**) {   cout << "b1::a1 (raw pointers)\n";    try {     b1 b1;   }   catch (...) {     cout << "exception thrown b1\n";   }    cout << "\nb2::a2 (unique pointers)\n";    try {     b2 b2;   }   catch (...) {     cout << "exception thrown b2\n";   }    cin.get();    return 0; } 

and output is:

b1::a1 (raw pointers) pointed() a1() exception thrown b1  b2::a2 (unique pointers) pointed() a2() ~pointed() exception thrown b2 

so, consequence unique_ptr deleted automatically when exception occurs in constructor of same class member declared.

with raw pointer can have double delete, since have no manually realized copy c-tor , assignment operator.

a a; b = a; // b.p_str store same address, a.p_str 

with unique_ptr can't copy/assign object, can move it, without writing move c-tor/move assignment operator.

a a; b = a; // cannot this, since `unique_ptr` has no copy constructor. b = std::move(a); // okay, `b` stores `unique_ptr` data , `a` stores `nullptr` 

but actually, have no idea, why should store pointer here, instead of object of type std::string, it's best solution in example.


Comments

Popular posts from this blog

searchKeyword not working in AngularJS filter -

sequelize.js - Sequelize: sort by enum cases -

user interface - how to replace an ongoing process of image capture from another process call over the same ImageLabel in python's GUI TKinter -