c++ - C++中的数组类成员初始化

标签 c++ arrays initialization

我有以下代码片段:

#include <iostream>
using namespace std;
class A {
    int* data;
    int size;
public:
    A(int s):size(s)
    {
        data = new int[size];
    }
    A() {
        data = nullptr;
    }
    ~A() {
        if (data) delete [] data;
    }
};
class B {
    A a[2];
public:
    B() {
        a[0] = A(10);
        a[1] = A(11); 
    }
};
int main(int argc, char *argv[]) {
    B b;
}

在上面的 C++ 代码中,我有 class A,它有一个 array 成员 int* data,并且(解除)分配内存由(de)构造函数处理。我创建了 B 类,它有一个固定长度的A 类数组 作为数据成员。

我的问题是:如何优雅地初始化成员A a[2]?上面的代码中,A(10)A(11)是在栈上创建的,当跳出作用域时,会调用它们的析构函数,因此数据无效。 main函数作用域跳转时,a[2]持有的指针会被释放两次,导致错误:

未分配正在释放的指针

一个可能的解决方案是仔细设计一个复制构造函数和一个移动构造函数,这样上面的编码范式就可以工作了。

我尝试过的另一个解决方案是在 class Binitialization list 中初始化数组:

B() : a { A(10), A(11) }

这个解决方案有效,我并没有真正告诉初始化列表的底层机制。我想这肯定与简单的构造复制有很大的不同。我真的希望有专家能对这个机制给出详细的解释。当然,这个解决方案是丑陋的硬编码且不灵活。

所以我想知道 C++ 中是否有一些编程范例来解决这个设计问题?

最佳答案

In the code above, the A(10) and A(11) are created on the stack

它们是临时对象。没有指定在哪里它们被创建或者它们是否被创建。

when jumping out of the scope, their destructors will be called

每个临时对象的析构函数将在相应的移动赋值语句结束后被调用。

One possible solution is to carefully design a copy constructor and a move constructor, by doing so the above coding paradigm could work.

还有 {copy,move} 赋值运算符。当隐式声明的那些没有做正确的事情时,你应该总是这样做。如果您在析构函数中删除某些内容,它们永远不会做正确的事情。

Another solution I've tried is to initialise the array in the initialization list of class B

This solution works and I don't really tell the underlying mechanism of initialization list. I think it must be quite different from simply construct and copy.

原始代码中的错误是 A 的移动赋值运算符的错误行为。由于初始化列表永远不会从临时对象中移动分配,因此它永远不会触发错误。

这实际上是构建您要求的 a 的更优雅的方法。不是因为它避免了错误,而是因为从本质上讲,避免不必要的移动是件好事。

So I wonder if there are some programming paradigms in C++ to tackle this design problem?

是的。 RAII Single responsibility principle .除非你的类除了管理 data 指向的内存之外什么都不做,否则它不应该管理内存。相反,它应该将内存管理委托(delegate)给 RAII 对象。在这种情况下,您应该使用 std::vector 成员。

class A {
    std::vector<int> data;
public:
    A(int s):data(s) {}
    A() = default;
};

关于c++ - C++中的数组类成员初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36860719/

相关文章:

c - 在缓冲区中高效地查找序列

javascript - JS 数组到对象的数组

c++ - T() 应该将成员变量初始化为零吗?

c++ - 使用 Visual Studio 从 C++ 代码调用程序集过程

c++ - GlowCode 与 AQTime C++ 现实世界中的分析性能对比?

c++ - 运算符重载 分数

c++ - 类成员初始化的最佳实践

c++ - 体系结构 x86_64 c++ 的 undefined symbol

c - C中数组指针问题

objective-c - -init 与 +initialize 的实现