如何将我自己的智能指针传递给函数?
How to pass my own smart pointer to function?
有智能指针class:
template <typename T>
class UniquePtr {
public:
UniquePtr(T* obj)
: obj(obj)
{
}
UniquePtr(const UniquePtr& ptr) = delete;
UniquePtr(UniquePtr&& ptr)
{
std::cout << "!! use of move !!" << std::endl;
obj = std::move(ptr.obj);
ptr.obj = nullptr;
}
UniquePtr& operator=(const UniquePtr& ptr) = delete;
UniquePtr& operator=(const UniquePtr&& ptr) = delete;
~UniquePtr()
{
delete obj;
}
private:
T* obj;
};
class 测试:
class Test {
public:
Test()
{
std::cout << "Test is created" << std::endl;
}
Test(const Test& obj) = delete;
Test(const Test&& obj) = delete;
Test& operator=(const Test& obj) = delete;
Test& operator=(const Test&& obj) = delete;
virtual ~Test()
{
std::cout << "Test is destructed" << std::endl;
}
};
和功能:
void function(UniquePtr<Test>&& ptr)
{
std::vector<UniquePtr<Test>> v;
v.push_back(std::move(ptr));
}
如果我通过测试class,一切正常:
UniquePtr<Test> ptr(new Test);
function(std::move(ptr));
但是如果我通过派生自测试 class,代码不会被编译:
class TestChild : public Test {
public:
TestChild()
{
std::cout << "Test child is created" << std::endl;
}
TestChild(const TestChild& obj) = delete;
TestChild(const TestChild&& obj) = delete;
TestChild& operator=(const TestChild& obj) = delete;
TestChild& operator=(const TestChild&& obj) = delete;
virtual ~TestChild()
{
std::cout << "Test child is destructed" << std::endl;
}
};
UniquePtr<TestChild> ptr(new TestChild);
function(std::move(ptr));
error: invalid initialization of reference of type ‘UniquePtr&&’ from
expression of type ‘std::remove_reference&>::type {aka UniquePtr}’
function(std::move(ptr)); ~~~~~~~~~^~~~~
如何将 UniquePtr<TestChild>
转换为 UniquePtr<Test>&&
使用 std::unique_ptr
此代码有效。
很像 std::unique_ptr
handles it,你需要为你的 class 提供一个模板化的构造函数,它采用不同类型的 UniquePtr
(允许 SFINAE 处理继承检查),然后将用于初始化您的 UniquePtr
的状态。
template<typename U>
UniquePtr(UniquePtr<U> && other) {
obj = other.obj;//Won't compile if U is not a subclass of T.
other.obj = nullptr;
}
有智能指针class:
template <typename T>
class UniquePtr {
public:
UniquePtr(T* obj)
: obj(obj)
{
}
UniquePtr(const UniquePtr& ptr) = delete;
UniquePtr(UniquePtr&& ptr)
{
std::cout << "!! use of move !!" << std::endl;
obj = std::move(ptr.obj);
ptr.obj = nullptr;
}
UniquePtr& operator=(const UniquePtr& ptr) = delete;
UniquePtr& operator=(const UniquePtr&& ptr) = delete;
~UniquePtr()
{
delete obj;
}
private:
T* obj;
};
class 测试:
class Test {
public:
Test()
{
std::cout << "Test is created" << std::endl;
}
Test(const Test& obj) = delete;
Test(const Test&& obj) = delete;
Test& operator=(const Test& obj) = delete;
Test& operator=(const Test&& obj) = delete;
virtual ~Test()
{
std::cout << "Test is destructed" << std::endl;
}
};
和功能:
void function(UniquePtr<Test>&& ptr)
{
std::vector<UniquePtr<Test>> v;
v.push_back(std::move(ptr));
}
如果我通过测试class,一切正常:
UniquePtr<Test> ptr(new Test);
function(std::move(ptr));
但是如果我通过派生自测试 class,代码不会被编译:
class TestChild : public Test {
public:
TestChild()
{
std::cout << "Test child is created" << std::endl;
}
TestChild(const TestChild& obj) = delete;
TestChild(const TestChild&& obj) = delete;
TestChild& operator=(const TestChild& obj) = delete;
TestChild& operator=(const TestChild&& obj) = delete;
virtual ~TestChild()
{
std::cout << "Test child is destructed" << std::endl;
}
};
UniquePtr<TestChild> ptr(new TestChild);
function(std::move(ptr));
error: invalid initialization of reference of type ‘UniquePtr&&’ from expression of type ‘std::remove_reference&>::type {aka UniquePtr}’ function(std::move(ptr)); ~~~~~~~~~^~~~~
如何将 UniquePtr<TestChild>
转换为 UniquePtr<Test>&&
使用 std::unique_ptr
此代码有效。
很像 std::unique_ptr
handles it,你需要为你的 class 提供一个模板化的构造函数,它采用不同类型的 UniquePtr
(允许 SFINAE 处理继承检查),然后将用于初始化您的 UniquePtr
的状态。
template<typename U>
UniquePtr(UniquePtr<U> && other) {
obj = other.obj;//Won't compile if U is not a subclass of T.
other.obj = nullptr;
}