从基类访问静态数组时出现段错误

sha*_*man 5 c++ memory arrays

我有这样的事情:

template <typename Item>
class Base
{
public:
    Base(Item* arr, int size):
        m_data(arr),
        m_size(size)
    {
        for (int i = 0; i < size; ++i)
        {
            arr[i] = Item();
        }
    }
private:
    Item* m_data;
    int m_size;
};

template<typename Item, unsigned int Size=0>

class Derived
{
public:
    Derived():
        Base<Item>(m_storage, Size)
    {
    }
private:
    Item m_storage[Size]
};
Run Code Online (Sandbox Code Playgroud)

所以我这样做的原因是我试图初始化存储以在基类中使用(覆盖性投诉),并且我意识到这可能是错误的方法,但我只是想知道当基类尝试写入数组时,为什么会出现段错误。我正在初始化一个大小为 3 的字符串,派生为它的项目类型,并且它在 for 循环的第一次迭代中出现段错误。

另请注意,我认为这可能不是解决我的覆盖性问题的方法,我有另一个解决方案,但我真的很好奇为什么它会出现分段错误,因为它应该能够访问数组。

谢谢您的帮助。

Mar*_*ork 1

您的问题是初始化顺序。

这个说法:

arr[i] = Item();
Run Code Online (Sandbox Code Playgroud)

假设左侧的项目已被初始化并且其生命周期已开始。即,赋值运算符是对已调用其构造函数的对象的赋值。

在你的情况下,这是不正确的。

如果我们看一下派生对象:

class Derived
{
public:
    Derived():
        Base<Item>(m_storage, Size)   // Here you are calling the base class
                                      // constructor where the above assignment
                                      // is actually being done.

      // But there is an implied initialization of the array
      // m_storage (that happens here).
      //
      // Before this point the memory for this array of object of
      // type <Item> has not been initialized (ie. no constructors
      // have been called).
      //
      // Yet you are using the array in the base class constructor
      // above.
      //
      // Note the initialization of this object done automatically
      // does a very similar thing to what you are doing in the base
      // class. i.e. Every member of the array is initialized using
      // the default constructor.
    {
    }
private:
    Item m_storage[Size]
};
Run Code Online (Sandbox Code Playgroud)