智能指针数组的正确初始化

Pav*_*yan 5 c++ arrays pointers initialization

对于这种情况:

    class A
    {
        //implementation
    };

    class B
    {
     public:
         B();
        ~B();
     private:
         std::vector<std::shared_ptr<A>> _innerArray;
    };
Run Code Online (Sandbox Code Playgroud)

我应该怎么做B()才能创建一个有效状态的对象?我是否需要为A数组中的每个对象手动调用默认构造函数?我需要做一些特别的事~B()吗?如果B类是糟糕设计的例子,请随意说如何使其更好.谢谢.

编辑 所以,这里有一个我真正需要的方案.

在此输入图像描述

因此,仅存储在A和所有其他对象的数组中的实际值用于存储连接.最简单的例子 - A =点,B =经过选定点的线(或曲线),C =由线描述的平面.希望它能让问题更加准确.

Mat*_*usz 5

要创建B处于有效状态的对象,您无需执行任何其他操作。您甚至不必声明和实现的构造函数和析构函数Bstd::vector<std::shared_ptr<A>>的成员B将在B的构造函数中默认初始化,这意味着它在容器中还没有任何元素。还要~B感谢std::vectorand std::shared_ptr析构函数,将其正确删除。

在另一方面,如果你比如要以某种方式初始化(即3个值),可以使用std::vectorstd::initializer_list构造函数在B类的构造函数初始化列表。例如:

class B
{
 public:
     B(): _innerArray{ std::make_shared<A>(),
                       std::make_shared<A>(),
                       std::make_shared<A>() } {}
    ~B() {}
 private:
     std::vector<std::shared_ptr<A>> _innerArray;
};
Run Code Online (Sandbox Code Playgroud)

请记住,它std::make_shared使用完美的转发,因此您将A的构造函数参数作为函数参数而不是类对象本身传递。

回答您对设计的担忧我想鼓励您在决定共享成员之前先考虑向量中成员的专有所有权。

class B
{
 public:
     B();
    ~B();
 private:
     std::vector<std::unique_ptr<A>> _innerArray;
};
Run Code Online (Sandbox Code Playgroud)

上述实施在许多方面都更为有效。首先,它使您的设计更清楚地了解谁对As 的生命负责。Next std::unique_ptr更快,因为它不需要线程安全的引用计数。最后但并非最不重要的一点是,它不花费任何额外的内存(与常规C指针相比),而std::shared_ptr存储共享的状态数据则可能需要数十个字节(24-48),而当您在小类上进行操作时,这是非常无效的。这就是为什么我总是将其std::unique_ptr用作首选的智能指针,而仅回退到std::shared_ptr真正需要它的原因。

编辑:

回答您的编辑我将创建类3个容器ABC。根据事实,如果您需要它们是否是多态的,我会存储两个这样的值(非多态类型):

std::deque<A> as;
std::deque<B> bs;
std::deque<C> cs;
Run Code Online (Sandbox Code Playgroud)

或(多态类型):

std::vector<std::unique_ptr<A>> as;
std::vector<std::unique_ptr<B>> bs;
std::vector<std::unique_ptr<C>> cs;
Run Code Online (Sandbox Code Playgroud)

按此顺序(as必须寿命长于bs并且bs必须寿命长于cs)。然后,我将只有std::vector<A*>内部B类和std::vector<B*>内部C类,而无需使用任何智能指针。

希望对您有所帮助。

编辑:

在第一种情况下更改std::vectorstd::deque,允许对容器元素的引用/指针在容器扩展中保留push_back()。但是,它们将无法幸免于擦除元素,排序或其他内容。