先上代码:
#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) 因为编译器在处理这种情况时会优化掉你的代码,类似:
所以你的move ctor没有调用。这个优化通常称为
Return Value Optimization(RVO)
,标准里称作 Copy Elision。如果你使用的是G++,你可以在编译参数里加入-fno-elide-constructors
来禁用这个优化,看看结果有何不同。