首页 > 关于c++11move copy contructor

关于c++11move copy contructor

先上代码:

#include <iostream>
//https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.4/a01404.html
template <typename T>
class my_unique_ptr{
private:
    T* p;

public:
    typedef T* pointer;//pointer() will return a null pointer
    my_unique_ptr():p(pointer()){}

    my_unique_ptr(pointer _p):p(_p){}

    //Move constructors
    my_unique_ptr(my_unique_ptr<T>&& __u): p(__u.release()){
        // function return  cannot cout
        std::cout << "move constructor" << std::endl;
    }

    //Assignment
    my_unique_ptr<T>& operator=(my_unique_ptr<T>&& __u){
        reset(__u.release());
        std::cout << "move assignment" << std::endl;
        return *this;
    }

    ~my_unique_ptr(){reset();}

    pointer get() const {return p;}

    pointer release(){
        T* __p = get();
        p = 0;
        return __p;
    }
    //pointer() here is nullptr
    void reset(pointer __p = pointer()){
        if(__p != get()){
            delete get();
            p = __p;
        }
    }

    pointer operator->() const {
        return get();
    }

    T& operator*() const{
        return *get();
    }

    //__u will be destroy soon
    void swap(my_unique_ptr<T>&& __u){
        using std::swap;//c++ primer
        swap(get(),__u->get());
    }

    //diable copy from lvalue.
    my_unique_ptr(const my_unique_ptr<T>&) = delete;
    my_unique_ptr<T>& operator=(const my_unique_ptr<T>&) = delete;
};

class Mint{
private:
    int a;
public:
    Mint():a(0){
        std::cout << "Cons: " << a << std::endl;
    }
    Mint(int t):a(t){
        std::cout << "Cons: " << a << std::endl;
    }

    ~Mint(){
        std::cout << "Des: " << a << std::endl;
    }
    void show(){
         std::cout << "show: " << a << std::endl;
    }

};
my_unique_ptr<Mint> test()
{
    my_unique_ptr<Mint> ret(new Mint(19));

    return ret;
}
my_unique_ptr<Mint> test2()
{
    return my_unique_ptr<Mint>(new Mint(20));
}
int main()
{
    typedef int* pin;
    std::cout << (pin()==nullptr) << std:: endl;
    my_unique_ptr<Mint> p1(new Mint(1));
    my_unique_ptr<Mint> p2(new Mint(2));
    p2.reset(p1.release());
    p2->show();
    my_unique_ptr<Mint> p4 = test();
    p4->show();
    my_unique_ptr<Mint> p5 = test2();
    p5->show();

    /*my_unique_ptr<Mint> cpy1 = std::move(p1);
    my_unique_ptr<Mint> cpy2;
    cpy2 = std::move(p2);
    cpy2->show();
    cpy1->show();*/

    //my_unique_ptr<Mint> pcpy = p5;
    //my_unique_ptr<Mint> pcpy2 = p4;

}

我参照源码实现一个unique_ptr,这里有几个问题

第一个问题:

typedef int* pin;
pin() 返回什么?  返回一个空指针,怎么解释?

第二个问题:
在test函数里面,返回一个my_unique_ptr指针,显然应该是调用MoveConstructor(注释掉该函数过后会报错),但是MoveConstructor内部的“move constructor”语句打印不出来。

即:my_unique_ptr<Mint> p4 = test(); 这里没有输出“move constructor”

在调用std::move 的时候,可以看到打印出来的“move constructor”

初学者,求指教。


1) 返回一个nullptr, 没有特殊的作用。

2) 因为编译器在处理这种情况时会优化掉你的代码,类似:

my_unique_ptr<Mint> p4(new Mint(19));

所以你的move ctor没有调用。这个优化通常称为Return Value Optimization(RVO),标准里称作 Copy Elision。如果你使用的是G++,你可以在编译参数里加入-fno-elide-constructors来禁用这个优化,看看结果有何不同。

【热门文章】
【热门文章】