我正在学习智能指针,但在将变量的预先存在位置分配给标准库的共享指针方面遇到了问题。
例如,假设有一个 int x 变量,你不知道它的值。对于普通指针,我只需要执行:
int* ptr;
ptr = &x;
我尝试过使用共享指针,以及...
std::tr1::shared_ptr<int> ptr;
ptr = std::make_shared<int> (&x)
所以我非常不清楚如何去做。
我正在学习智能指针,但在将变量的预先存在位置分配给标准库的共享指针方面遇到了问题。
例如,假设有一个 int x 变量,你不知道它的值。对于普通指针,我只需要执行:
int* ptr;
ptr = &x;
我尝试过使用共享指针,以及...
std::tr1::shared_ptr<int> ptr;
ptr = std::make_shared<int> (&x)
所以我非常不清楚如何去做。
通常情况下,您不会使智能指针指向已存在的变量。智能指针管理动态分配对象的生命周期,在使用后删除它;如果将其指向未经动态分配的内容,则在尝试删除时会导致错误。
通常会使用new
或make_shared
来创建一个对象,并使用该结果创建或分配一个智能指针:
std::shared_ptr<int> ptr(new int(42)); // Create a new pointer to manage an object
ptr.reset(new int(66)); // Reset to manage a different object
ptr = std::make_shared<int>(53); // Use `make_shared` rather than `new`
make_shared
通常比 new
更可取,因为它更好地利用了内存,并提供了更强的异常安全性。
共享指针用于管理动态分配的内存,更准确地说,它们管理此内存的所有权。
基本上,智能指针是资源获取即初始化或RAII的实现。我强烈建议您查看这个原则,因为它非常有用,可以管理资源所有权(基本上,每次需要获取和释放资源时,无论是内存、数据库连接、文件处理程序、互斥量等)。
它的作用基本上是保证只要有人指向它所管理的动态分配的内存,那么这个内存就会可用,并且只要指向该内存的最后一个(智能)指针超出其作用域,那么delete
就会被调用。
因此,对于具有自动存储期的变量(即当它们超出范围或它们所属的对象本身超出范围或被删除(如果它是新的)时被删除),使用智能指针是没有意义的。
// dynamically via shared_ptr:
// shared_ptrs share the pointer to the Deleter
// because they already share a common data structure for reference counting.
auto ignore = [](int* o){
std::cout<<"i will refuse to delete this object: " << o << "\n";
std::cout<<"not my responsibility." <<std::endl;
};
std::shared_ptr<int> sptr(&x,ignore);
//statically via unique_ptr:
// actually, the unique_ptr is as data structure not more than a regular pointer.
// but a pointer with special copy-constructor and destructor,
// which will most likely be inlined.
// there is no space to store a reference to a Deleter dynamically.
struct IgnorantDeleter{
void operator()(int* o){
std::cout<<"who ate my cake? " << o << "\n";
std::cout<<"but i baked it." <<std::endl;
}
};
std::unique_ptr<int,IgnorantDeleter> uptr(&x);
不应该创建指向非动态分配对象的智能指针。否则,智能指针可能尝试删除已分配的内存,从而导致错误。