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
Post a Comment