通过将参数传递给构造函数来static_cast
unique_ptr
void *
时,我遇到了问题。特别是你在object3
中看到的.
解决方案在编译时很重要,智能指针的类型必须与堆叠对象的类型相同。
有什么解决办法吗?
class Test {
public:
Test(){}
Test(int n) : num(n) {}
int num;
};
template<typename T>
class Object {
public:
Object(T&& v) : value(static_cast<T*>(std::move(&v))) {}
Object(const T& v) : value(static_cast<T*>(&v)) {}
Object(std::unique_ptr<T>&& v) : value(static_cast<std::unique_ptr<T>*>(std::move(&v))) {}
Object(const std::unique_ptr<T>& v) : value(static_cast<std::unique_ptr<T>*>(&v)) {}
T* operator->() { return static_cast<T*>(value); }
private:
void* value;
};
int main(int argc, char *argv[]) {
Object<Test> object1 = Test(1);
cout << object1->num << endl; // print 1
Object<Test> object2 = Test();
object2->num = 2;
cout << object2->num << endl; // print 2
Object<Test> object3 = std::make_unique<Test>(3);
cout << object3->num << endl; // print 0 ¿?¿?¿?
Object<Test> object4 = std::make_unique<Test>();
object4->num = 4;
cout << object4->num << endl; // print 4
return 0;
}
结果:
1
2
0
4
也许你想要:
template<typename T>
class Object {
public:
Object(const T& v) : value(v) {}
Object(const std::unique_ptr<T>& v) : value(*v) {}
T* operator->() { return &value; }
private:
T value;
};
所以你不会再有悬空的指针了。
演示
有关更多类似指针语义的信息:
template<typename T>
class Object {
public:
Object(const T& v) : value(std::make_shared(v)) {}
Object(std::unique_ptr<T>&& v) : value(std::move(v)) {}
T* operator->() { return value.get(); }
private:
std::shared_pointer<T> value;
};
演示
你注意到的是未定义的行为。
unique_ptr的生存期不是您所期望的。
Object<Test> object3 = std::make_unique<Test>(3);
cout << object3->num << endl; // print 0 ¿?¿?¿?
你做一个临时unique_ptr,然后在构造函数中获取该临时的地址。
Object(std::unique_ptr<T>&& v) : value(static_cast<std::unique_ptr<T>*>(std::move(&v))) {}
在此语句中,您获取该unique_ptr的地址,然后移动该指针。 对于原始指针,这没有额外的效果。
对于您的每个语句,您可能会得到相同的意外结果,因为它们都使用临时语句。
请注意,您还编写了从unique_ptr到原始指针的reinterpret_cast。