将数组指针从派生类传递给基类C ++

时间:2014-06-23 15:56:07

标签: c++ arrays

我试图理解C ++中的继承。

我想在派生类中动态创建一个数组,并将数组指针传递给基类,然后基类填充数组。最后,我想从派生类中打印数组。

我编写了以下代码,但是当我运行此代码时,程序崩溃并且出现分段错误错误。

我该如何实现?!

class Base {
private:
    int* array;
public:
    Base(int* a) {
        array = a;
        for(int i = 0 ; i < 10 ; i++) {
            array[i] = i;
        }
    }
};

class Child : public Base {
private:
    int* array;
public:
    Child() : array(new int[10]), Base(array) {}
    void print() {
        for(int i = 0 ; i < 10 ; i++) {
            cout << array[i] << endl;
        }
    }
};

4 个答案:

答案 0 :(得分:5)

这里的问题是初始化列表中的项目顺序不会影响实际执行初始化的顺序;只考虑声明成员的顺序。而且,基数的初始化总是先发生。

因此,Child构造函数实际执行如下:

    调用
  • Base(array)(此处未设置array!)
  • array被分配了有效值。

幸运的是,解决此问题所需要做的就是从array中移除Child:无论如何它都是多余的:

class Child : public Base {
public:

    Child() : Base(new int[10]) {
    }

    void print() {
        for(int i = 0 ; i < 10 ; i++) {
            // Make a[] protected in the parent
            cout << a[i] << endl;
        }
    }
};

class Base
{
protected:
    int *array;
...
}

如果您不想在父级中保护a,则可以按照以下方式修改代码(demo):

Child() : Base(array = new int[10]) {}

这不是最理想的,因为冗余成员会保留在Child的所有实例中。

答案 1 :(得分:3)

即使您以其他顺序编写初始化程序,也会在类成员之前初始化基础子对象。所以这里:

Child(): array(new int[10]), Base(array)

首先使用未初始化的Base值初始化array对象。

解决方案包括:

  • Base::array访问Child,因此它不需要自己的副本;
  • print移至基类中,以便Child无需访问array;
  • 如果出于某种原因确实需要一个无法访问的变量的冗余副本,
  • 做一些像Child() : Base(array = new int[10])这样令人讨厌的事情。

确保您已启用编译器警告;他们应该抓住这个错误。

答案 2 :(得分:0)

这是因为首先构造了基础对象,然后才构造子对象。

这意味着您的阵列是未初始化的。

在每个招聘人员的开头和结尾放置一些跟踪消息,您将更好地了解事情的运作方式。

答案 3 :(得分:0)

一种解决方案是使用std::array代替原始指针,如下例所示:

#include <iostream>
#include <array>

template<typename T, std::size_t N>
class Base
{
private:
    std::array<T, N> const &array;
public:
    Base(std::array<T, N> const &a) : array(a) { }
    void print() const {
      std::cout << "Printing array from Base class!" << std::endl;
      for(auto i : array) std::cout << i << " ";
      std::cout << std::endl;
    }
};

template<typename T, std::size_t N>
class Child : public Base<T, N> {
private :
  std::array<T, N> array;
public:
  Child() : Base<T, N>(array) { 
    for(auto &i : array) i = 10;
  }

  void print() {
    std::cout << "Printing array from Child class!" << std::endl;
    for(auto i : array) std::cout << i << " ";
    std::cout << std::endl;
  }
};

auto main() -> int {
  Child<int, 10> c;
  c.print();
  Base<int, 10> *b = &c;
  b->print();

  return 0;
}

Live Demo


因此:

  • 您不必担心释放以前分配的内存。

  • 您的Base类保持对Child类的数组对象的常量引用。因此,您节省了内存。