我有一类,我希望其中一个函数将唯一的ptr对象传递给char数组。但是我对唯一指针的一些功能感到困惑。我知道当没有更多引用引用该对象时,析构函数会被自动调用,但对于原始变量还是相同的?例如,如果我这样做,会删除内存吗?
class A {
private:
public:
A(std::unique_ptr<char[]> data) {
data = nullptr;
}
~A();
};
int main() {
auto data = std::make_unique<char[]>(10);
A a(std::move(data));
return 0;
}
下一个问题是:如果我有一个要指向数据的私有对象,为什么会导致编译器错误?
class A {
private:
std::unique_ptr<char[]> internaldata;
public:
A(std::unique_ptr<char[]> data) {
internaldata = data;
}
~A() {
internaldata = nullptr;
}
};
int main() {
auto data = std::make_unique<char[]>(10);
A a(std::move(data));
return 0;
}
但是,当我在分配它时调用std :: move时,代码可以正常编译。
class A {
private:
std::unique_ptr<char[]> internaldata;
public:
A(std::unique_ptr<char[]> data) {
internaldata = std::move(data);
}
~A() {
internaldata = nullptr;
}
};
int main() {
auto data = std::make_unique<char[]>(10);
A a(std::move(data));
return 0;
}
但是为什么我必须在这里两次调用std :: move?一次传递参数,然后传递第二个参数?在此过程中,在引用计数方面究竟发生了什么,是否发生了重新分配,复制和删除?
最后,是否有可能在减速期间将数据传递到智能指针?因为目前我是这样的:
auto data = std::make_unique<char[]>(10);
char* buf = data.get();
strcpy(buf, "hello\0");
但是可以按照以下方式做些事情:
char hellobuffer[] = "hello";
auto data = std::make_unique<char[]>(hellobuffer);
在哪里自动为数据分配了存储hellobuffer和在数据本身上进行复制所需的正确大小?
答案 0 :(得分:4)
我知道当没有更多对象引用时析构函数会被自动调用,但对于原始变量仍然是相同的吗?
析构函数始终在逻辑上被调用。但是,由于int
和char
之类的东西都是微不足道的,因此编译器了解到实际上不应调用任何东西。
例如,如果我这样做,是否会删除内存?
是的-std::unique_ptr<T>
的全部意义在于您的记忆会自动得到照顾。
A(std::unique_ptr<char[]> data) {
internaldata = data;
}
该示例无法编译,因为internaldata = data
正在调用复制分配运算符,并且不允许复制std::unique_ptr
实例(因此具有唯一位)。
在该过程中引用计数方面究竟发生了什么,是否发生了重新分配,复制和删除?
没有引用计数-std::unique_ptr
引用某内容或为空。当您从std::move
std::unique_ptr
时,move-from变量变为空。如果要查找引用计数的指针类型,请参见std::shared_ptr<T>
。
最后,是否有可能在减速期间将数据传递到智能指针?
不。对于std::make_unique<T[]>
,仅允许您传递std::size_t
(请参阅overload 2)。为您要寻找的内容编写包装函数应该很容易。