简体   繁体   English

类中的智能指针?

[英]Smart pointers inside classes?

I'm having a following example of class template: 我有一个下面的类模板示例:

template<class T>
class MyContainer{
public:
    T* myArray;
    int size;
    MyContainer(int n) : size(n){
        myArray = new T[n];
    }
    ~MyContainer(){
        delete[] myArray;
    }
};

Is it possible to use smart pointers like unique_ptr or shared_ptr for myArray so I don't need to deallocate it in destructor? 是否可以为myArray使用诸如unique_ptr或shared_ptr之类的智能指针,所以我不需要在析构函数中对其进行分配? How? 怎么样?

Yes you can, and you really should : 是的,您可以,而且您确实应该:

template<class T>
class MyContainer{
public:
    std::unique_ptr<T[]> myArray;
    int size;
    MyContainer(int n) : myArray(new T[n]), size(n) { }
};

int main() {
  MyContainer<int> c(10);
}

Or if possible, pass the size as a template parameter : 或者,如果可能,将size作为模板参数传递:

template<class T, std::size_t N>
class MyContainer{
public:
    std::unique_ptr<T[]> myArray;
    int size = N;
    MyContainer() : myArray(new T[N]) { }
};

int main() {
  MyContainer<int, 10> c;
}

Or, if possible, just use std::vector<> or std::array<> 或者,如果可能,只需使用std::vector<>std::array<>

Notes: 笔记:

  • Variable lengths arrays are non standard. 可变长度数组是非标准的。
  • You should initialize class members in their order of declaration. 您应该按照声明的顺序初始化类成员。
  • The size should be an unsigned ( std::size_t ) 大小应为unsignedstd::size_t
template<class T>
class MyContainer{
public:
    unique_ptr<T[]> myArray;
    int size;
    MyContainer(int n) : size(n), myArray(new T[n]) {}
};

The smart-pointer must use the array deallocator, otherwise it's UB, though in the case of trivial types probably the same code. 智能指针必须使用数组取消分配器,否则为UB,尽管对于普通类型,可能是相同的代码。

Take a look here for the whole std::unique_ptr interface. 在这里查看整个std::unique_ptr接口。

Not only can you, but you really should. 您不仅可以,而且您确实应该。 Programmers are often surprised to discover that if a constructor throws an exception (which is the recommended way to signal that an object can't be created for any reason), the destructor is not run , because there's no general way for the compiler to know which lines in the destructor correspond to which lines in the constructor. 程序员通常会惊讶地发现,如果构造函数引发异常(这是表示由于某种原因无法创建对象的建议方式), 则析构函数不会运行 ,因为编译器没有通用的方法可以知道析构函数中的哪些行对应于构造函数中的哪些行。

On the other hand, any objects that have been created are destroyed because there is a general way to know which ones need to be destroyed. 另一方面,已创建的任何对象都将销毁,因为有一种通用方法可以知道需要销毁哪些对象。 To put it another way, if your object had two raw pointers, and the first call to new succeeded, but the second failed, the destructor wouldn't be run, and the first pointer would never be delete d. 换句话说,如果您的对象有两个原始指针,并且第一个对new调用成功,但是第二个失败,则不会运行析构函数,并且第一个指针将永远不会被delete d。 But if your object had two smart pointers, and the first was constructed successfully and the second failed, the first smart pointer would be properly destroyed and you wouldn't have to worry about it. 但是,如果您的对象有两个智能指针,并且第一个成功构造,而第二个失败,则第一个智能指针被正确销毁,而您不必担心它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM