默认构造函数,拷贝构造函数,移动构造函数实例

默认构造函数,拷贝构造函数,移动构造函数实例,第1张

默认构造函数拷贝构造函数,移动构造函数实例

直接上例子,更能清楚的显示区别:
(例子参考自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:

#include
using 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:

#include 

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;
	}
    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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5611271.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存