【发布时间】:2017-08-16 22:01:02
【问题描述】:
最近我尝试实现我自己的智能指针版本。实现看起来有点像下面:
class Var {
private:
void* value;
unsigned short* uses;
public:
Var() : value(nullptr), uses(new unsigned short(1)) { }
template<typename K>
Var(K value) : value((void*)new K(value)), uses(new unsigned short(1)) { }
Var(const Var &obj) {
value = obj.value;
(*(uses = obj.uses))++;
}
~Var() {
if (value == nullptr && uses == nullptr) return;
if (((*uses) -= 1) <= 0) {
delete value;
delete uses;
value = uses = nullptr;
}
}
Var& operator=(const Var& obj) {
if (this != &obj) {
this->~Var();
value = obj.value;
(*(uses = obj.uses))++;
}
return *this;
}
};
实现应该是直截了当的,因为value 持有指针,uses 计算引用。
请注意,指针存储为void*,并且指针类未固定为某些(通用)类型。
问题
智能指针在大多数情况下都在发挥作用……但以下情况除外:
class C {
public:
Var var;
C(Var var) : var(var) {}
};
void test() {
std::string string = std::string("Heyo");
Var var1 = Var(string);
C c = C(var1);
Var var2 = Var(c);
}
void main() {
test();
}
运行该代码时,第一个实例var1 在test 运行后不会被删除。
是的,使用void* 并不是最好的方法。然而,让我们不要离开话题。代码编译得非常好(如果有人可能会质疑我对子分配运算符的使用)。如果错误出现在删除 void* 中,则引用计数器 uses 将被删除,但事实并非如此。
我之前已经检查过析构函数,它们都被调用了。
还要注意程序运行时没有错误。
提前谢谢大家,
谢尔顿
【问题讨论】:
-
您有哪些标准库版本无法满足的“需求”?
-
@Sheldon,在
void*上调用delete是不对的。见timsong-cpp.github.io/cppwp/n3337/expr.delete#1。 -
你可能有多个错误,但
void*的东西是一个破坏整个概念的阻碍。 ideone.com/t02HsI 请注意,析构函数没有为void*运行 -
@Sheldon:如果您的代码具有未定义的行为,那么它是否可以正常工作并不重要。还是错了。
标签: c++ pointers smart-pointers