直接上例子,更能清楚的显示区别:
(例子参考自c++ primer 5th 课后题)
例子1:
#include#include using namespace std; struct X { X() { std::cout << "X()" << std::endl; } X(const X&) { std::cout << "X(const X&)" << std::endl; } X& operator= (const X& x); ~ X() { std::cout << "~X()" << std::endl; } }; X& X::operator=(const X& x) { // 实际上这里没有输出 std::cout << "=X()" << std::endl; } void f (X& x1, X* x2) { vector xvec; xvec.push_back(x1); xvec.push_back(*x2); cout << "------- destructor in f -----" << endl; } int main(){ cout << "------- constructor -----" << endl; X x1; X *x2 = new X(); cout << "------- copy constructor -----" << endl; f (x1, x2); // f()结束会调用一次析构 cout << "------- destructor 1-----" << endl; delete x2; cout << "------- destructor 2-----" << endl; return 0; }
运行结果:
这里有个STL的知识点,为什么会在------- copy constructor -----之后会再拷贝一次和析构一次,因为vector容器一开始给的capable_size是1,当你push_back第二的对象时,就要重新开辟空间(一般来说是按照两倍空间扩容为2),把原来的东西拷贝过去,然后析构原来的空间,所以这里多调用了一次拷贝和析构。对应的你要push_back第三个时就会再次扩容(再次两倍空间扩容为4),大家可以自己试试,这里就不再展示。
------- constructor -----
X()
X()
------- copy constructor -----
X(const X&)
X(const X&)
X(const X&)
~X()
------- destructor in f -----
~X()
~X()
------- destructor 1-----
~X()
------- destructor 2-----
~X()
例子2:
#includeusing namespace std; // .h文件 class HasPtr { friend void swap(HasPtr&, HasPtr&); public: HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0){} HasPtr(const HasPtr& hp) : ps (new std::string(*hp.ps)), i (hp.i) {} HasPtr& operator= (const HasPtr& hp) { auto newp = new std::string(*hp.ps); delete ps; ps = newp; i = hp.i; return *this; } std::string& getPs() { return *ps; } ~HasPtr () { delete ps; } private: std::string *ps; int i; }; inline void swap(HasPtr& lhs, HasPtr& rhs) { using std::swap; swap (lhs.ps, rhs.ps); swap (lhs.i, rhs.i); std::cout << "call the swap function." << std::endl; } // 测试 .cpp int main() { HasPtr hp1 ("hello"); HasPtr hp2 ("world"); swap(hp1, hp2); cout << hp1.getPs() << endl; cout << hp2.getPs() << endl; return 0; }
运行结果:
call the swap function.
world
hello
例子3:
#include#include #include using namespace std; // .h文件,注意要重写operator=、swap函数;新增operator<函数。 class HasPtr { friend void swap(HasPtr&, HasPtr&); friend bool operator< (HasPtr& lhs, HasPtr& rhs); public: HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0){} HasPtr(const HasPtr& hp) : ps (new std::string(*hp.ps)), i (hp.i) {} HasPtr& operator= (HasPtr hp) { this->swap(hp); std::cout << "call operator=(HasPtr &rhs)" << std::endl; return *this; } void swap(HasPtr &rhs) { using std::swap; swap(ps, rhs.ps); swap(i, rhs.i); // std::cout << rhs.getPs(); std::cout << "call swap(HasPtr &rhs)" << std::endl; } std::string& getPs() { return *ps; } ~HasPtr () { delete ps; } private: std::string *ps; int i; }; void swap(HasPtr& lhs, HasPtr& rhs) { lhs.swap(rhs); } bool operator< (HasPtr& lhs, HasPtr& rhs) { std::cout << lhs.getPs() <<" "< hvec; hvec.push_back(hp1); hvec.push_back(hp2); hvec.push_back(hp3); std::sort (hvec.begin(), hvec.end()); for (auto i : hvec) { cout << i.getPs() << endl; } return 0; }
运行结果:
具体底层是怎么实现的有知晓的小伙伴可以评论区补充一下。
hello Anna 0
hello Anna 0
call swap(HasPtr &rhs)
call operator=(HasPtr &rhs)
world Anna 0
world hello 0
call swap(HasPtr &rhs)
call operator=(HasPtr &rhs)
Anna
hello
world
例子4:
#includeclass HasPtr { friend void swap(HasPtr&, HasPtr&); friend bool operator< (HasPtr& lhs, HasPtr& rhs); public: HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0){} HasPtr(const HasPtr& hp) : ps (new std::string(*hp.ps)), i (hp.i) {} HasPtr& operator= (HasPtr hp) { this->swap(hp); std::cout << "call operator=(HasPtr &rhs)" << std::endl; return *this; } HasPtr (HasPtr&& hp) noexcept; // HasPtr& operator= (HasPtr&& hp) noexcept; void swap(HasPtr &rhs) { using std::swap; swap(ps, rhs.ps); swap(i, rhs.i); std::cout << "call swap(HasPtr &rhs)" << std::endl; } std::string& getPs() { return *ps; } ~HasPtr () { delete ps; } private: std::string *ps; int i; }; void swap(HasPtr& lhs, HasPtr& rhs) { lhs.swap(rhs); } // HasPtr.cpp using namespace std; HasPtr::HasPtr(HasPtr&& hp) noexcept : ps (hp.ps), i (hp.i) { hp.ps = nullptr; cout << "call move constructor." << endl; } int main() { HasPtr hp1("hello"), hp2("world"); //hp1 = hp2; hp1 = std::move (hp2); cout << hp1.getPs() << endl; return 0; }
运行结果:
call move constructor.
call swap(HasPtr &rhs)
call operator=(HasPtr &rhs)
world
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)