为 C++03 编译器编写部分 unique_ptr,它使用较新的编译器在通用代码库上运行
Writing partial unique_ptr for C++03 compiler which operates on common codebase with newer compilers
我需要为 C++03 编写 unique_ptr
的实现,它只会吸收在启用 C++11 的其他平台下对公共代码库所做的更改。也就是说,它不需要检查任何东西,一切都会被其他平台的编译器检查。但它需要正确传递和销毁对象。
这是测试代码示例。还有 full test online.
template <class T> std2::unique_ptr<T> pass_through(std2::unique_ptr<T> p) { return p; }
...
std2::unique_ptr<A> a1 = std2::make_unique<B>();
std2::unique_ptr<A> a2 = std2::move(pass_through(a1)); // doesn't work
std2::unique_ptr<A> a2 = (const std2::unique_ptr<A>&)std2::move(pass_through(a1)); // doesn't work
std2::unique_ptr<A> a2 = (const std2::unique_ptr<B>&)std2::move(pass_through(a1)); // works
std2::unique_ptr<B> a2 = std2::move(pass_through(a1)); // works
unique_ptr 实施:
class Num { protected: static int i; }; int Num::i = 0;
template<class Data>
class unique_ptr : Num
{
int _i = i++;
mutable Data *_data;
public:
explicit unique_ptr(Data* data = nullptr)
{ _data = data; std::cout << _i << ": cons" << std::endl; }
template<class T>
unique_ptr(unique_ptr<T>& other) :
_data((Data*)other.release())
{ std::cout << _i << ": copy cons <T>" << std::endl; }
template<class T>
unique_ptr(const unique_ptr<T>& other) :
_data((Data*)other.release())
{ std::cout << _i << ": copy cons const <T>" << std::endl; }
~unique_ptr() { std::cout << _i << ": deleting :" << _data << std::endl; delete _data; _data = 0; }
unique_ptr& operator=(Data* data)
{ reset(data); return *this; }
template<class T>
unique_ptr& operator=(unique_ptr<T>& other) {
std::cout << "assign <T>" << std::endl;
reset((Data*)other.release());
return *this;
}
template<class T>
unique_ptr& operator=(const unique_ptr<T>& other) {
std::cout << "assign const <T>" << std::endl;
reset((Data*)other.release());
return *this;
}
operator bool() const { return _data != nullptr; }
Data* release() const
{ Data* res = _data; _data = nullptr; return res; }
template <class T>
void reset(T* data)
{ Data* old = _data; _data = (Data*)data; delete old; }
};
template <class T> std2::unique_ptr<T>& move( std2::unique_ptr<T>& data) { return data; }
template <class T> const std2::unique_ptr<T>& move(const std2::unique_ptr<T>& data) { return data; }
template<class Data>
inline unique_ptr<Data> make_unique() { return unique_ptr<Data>(new Data()); }
类:
struct A {
A() { std::cout << "A()" << std::endl; }
virtual ~A() { std::cout << "~A()" << std::endl; };
};
struct B : public A {
B() : A() { std::cout << "B()" << std::endl; }
~B() { std::cout << "~B" << std::endl; };
};
第一个选项的输出。看起来已经完成了一些额外的复制(memcpy)。
A()
B()
0: cons
1: copy cons const <T>
0: deleting :0000000000000000
2: copy cons <T>
Inside pass_through
3: copy cons <T>
2: deleting :0000000000000000
3: deleting :000001CC492B1790 // This one is #3
~B
~A()
3: deleting :000001CC492B1790 // This one is also #3
你能帮我解决这个双重删除问题吗?
模板永远不是复制构造函数。
unique_ptr(const unique_ptr<Data>& other)
unique_ptr(unique_ptr<Data>& other)
写这两个。
operator=
也类似。
我需要为 C++03 编写 unique_ptr
的实现,它只会吸收在启用 C++11 的其他平台下对公共代码库所做的更改。也就是说,它不需要检查任何东西,一切都会被其他平台的编译器检查。但它需要正确传递和销毁对象。
这是测试代码示例。还有 full test online.
template <class T> std2::unique_ptr<T> pass_through(std2::unique_ptr<T> p) { return p; }
...
std2::unique_ptr<A> a1 = std2::make_unique<B>();
std2::unique_ptr<A> a2 = std2::move(pass_through(a1)); // doesn't work
std2::unique_ptr<A> a2 = (const std2::unique_ptr<A>&)std2::move(pass_through(a1)); // doesn't work
std2::unique_ptr<A> a2 = (const std2::unique_ptr<B>&)std2::move(pass_through(a1)); // works
std2::unique_ptr<B> a2 = std2::move(pass_through(a1)); // works
unique_ptr 实施:
class Num { protected: static int i; }; int Num::i = 0;
template<class Data>
class unique_ptr : Num
{
int _i = i++;
mutable Data *_data;
public:
explicit unique_ptr(Data* data = nullptr)
{ _data = data; std::cout << _i << ": cons" << std::endl; }
template<class T>
unique_ptr(unique_ptr<T>& other) :
_data((Data*)other.release())
{ std::cout << _i << ": copy cons <T>" << std::endl; }
template<class T>
unique_ptr(const unique_ptr<T>& other) :
_data((Data*)other.release())
{ std::cout << _i << ": copy cons const <T>" << std::endl; }
~unique_ptr() { std::cout << _i << ": deleting :" << _data << std::endl; delete _data; _data = 0; }
unique_ptr& operator=(Data* data)
{ reset(data); return *this; }
template<class T>
unique_ptr& operator=(unique_ptr<T>& other) {
std::cout << "assign <T>" << std::endl;
reset((Data*)other.release());
return *this;
}
template<class T>
unique_ptr& operator=(const unique_ptr<T>& other) {
std::cout << "assign const <T>" << std::endl;
reset((Data*)other.release());
return *this;
}
operator bool() const { return _data != nullptr; }
Data* release() const
{ Data* res = _data; _data = nullptr; return res; }
template <class T>
void reset(T* data)
{ Data* old = _data; _data = (Data*)data; delete old; }
};
template <class T> std2::unique_ptr<T>& move( std2::unique_ptr<T>& data) { return data; }
template <class T> const std2::unique_ptr<T>& move(const std2::unique_ptr<T>& data) { return data; }
template<class Data>
inline unique_ptr<Data> make_unique() { return unique_ptr<Data>(new Data()); }
类:
struct A {
A() { std::cout << "A()" << std::endl; }
virtual ~A() { std::cout << "~A()" << std::endl; };
};
struct B : public A {
B() : A() { std::cout << "B()" << std::endl; }
~B() { std::cout << "~B" << std::endl; };
};
第一个选项的输出。看起来已经完成了一些额外的复制(memcpy)。
A() B() 0: cons 1: copy cons const <T> 0: deleting :0000000000000000 2: copy cons <T> Inside pass_through 3: copy cons <T> 2: deleting :0000000000000000 3: deleting :000001CC492B1790 // This one is #3 ~B ~A() 3: deleting :000001CC492B1790 // This one is also #3
你能帮我解决这个双重删除问题吗?
模板永远不是复制构造函数。
unique_ptr(const unique_ptr<Data>& other)
unique_ptr(unique_ptr<Data>& other)
写这两个。
operator=
也类似。