c++ - 如果派生类具有私有(private)变量,则派生类数组不起作用

标签 c++ arrays pointers polymorphism

我有一个抽象基类和 2 个实现基类虚函数的不同类。

我将它们放在一个数组中,对于“derived1”类,这是可行的。 但是,如果我创建一个包含一些额外私有(private)变量的“derived2”类数组,代码将编译但在运行时出错。

#include <iostream>
class base{
protected:
  int inner_a;
  int inner_b;
public:
  void setInner(int a,int b){inner_a=a;inner_b=b;};
  virtual int doStuff()=0;
};


class derived1: public base{
public:
  virtual int doStuff();
};



class derived2: public base{
private:
  int tmpVar;//works if I remove
public:
  int doStuff();
};


int derived2::doStuff(){

  return inner_a-inner_b;
}

int derived1::doStuff(){
    return inner_a+inner_b;
}



int main(){
  base *classAry1 = new derived1[3];//this works
  base *classAry2 = new derived2[2];//derived2 has extra private variables


  classAry1[0].setInner(1,3);
  classAry1[1].setInner(10,7);
  std::cout <<classAry1[0].doStuff() <<std::endl;;
  std::cout <<classAry1[1].doStuff() <<std::endl;


  classAry2[0].setInner(1,3);
  classAry2[1].setInner(10,7);
  std::cout <<classAry2[0].doStuff() <<std::endl;;
  std::cout <<classAry2[1].doStuff() <<std::endl;


  return 0;
}

谁能帮我解决如何将派生类放入标准数组中的问题?

谢谢

编辑:

代码段错误,valgrind 告诉我

-2

==25096== Use of uninitialised value of size 8
==25096==    at 0x400AC9: main (abc.cpp:52)
==25096== 
==25096== Invalid read of size 8
==25096==    at 0x400AC9: main (abc.cpp:52)
==25096==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==25096== 
==25096== 
==25096== Process terminating with default action of signal 11 (SIGSEGV)
==25096==  Access not within mapped region at address 0x0
==25096==    at 0x400AC9: main (abc.cpp:52)

最佳答案

derived1 对象(或 derived2 对象)的数组 不能解释为 数组>base 对象。数组不是多态的。只有独立对象可以是多态的,即 derived1base 具有 IS-A 关系。但是array of derived1array of base没有IS-A关系。您的数组(classAry1classAry2)都不能真正“工作”。

也就是说,这个

base *classAry1 = new derived1[3];
base *classAry2 = new derived2[2];

已经没有任何意义,即使它是形式上格式正确的代码。

第一个数组“似乎可以工作”纯属偶然。即使您使用 classAry1,您的代码的行为也是未定义的。

如果您想要一个存储多态实体的数组(或容器),您必须存储指向该数组中实际对象的指针,而不是存储实际对象本身。

在您的特定情况下,可以按以下方式重写代码。 (它看起来不太好,我这样做只是为了说明原理,因为在不知道你的全部意图的情况下很难选择最好的方法)

int main(){
  derived1 *d1s = new derived1[2];
  base **classAry1 = new base *[2];
  classAry1[0] = &d1s[0];
  classAry1[1] = &d1s[1];

  derived2 *d2s = new derived2[2];
  base **classAry2 = new base *[2];
  classAry2[0] = &d2s[0];
  classAry2[1] = &d2s[1];

  classAry1[0]->setInner(1,3);
  classAry1[1]->setInner(10,7);
  std::cout << classAry1[0]->doStuff() << std::endl;;
  std::cout << classAry1[1]->doStuff() << std::endl;

  classAry2[0]->setInner(1,3);
  classAry2[1]->setInner(10,7);
  std::cout << classAry2[0]->doStuff() << std::endl;;
  std::cout << classAry2[1]->doStuff() << std::endl;

  delete[] classAry2;
  delete[] d2s;
  delete[] classAry1;
  delete[] d1s;

  return 0;
}

关于c++ - 如果派生类具有私有(private)变量,则派生类数组不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6272676/

相关文章:

Javascript 对象/数组问题?

c++ - 空字符行为 C++

c - 如何将 dlsym 返回的指针正确赋值给函数指针类型的变量?

c++ - 如何使用带有 QML 信号的自定义 Qt 类型?

c++ - 为什么我可以在单个文件中乱序初始化两个静态类变量而不是三个?

c++ - 当键分配字符串时,Map 是否有优化版本?

javascript - Json数据修改为新的键值对JavaScript

c++ - 我无法在我的macOS 10.14中的任何地方编译.cpp文件,但无法编译IDE项目生成的目录(例如Xcode或CLion)

使用指针创建列表

c - 从文本文件中读取字符串以构建二叉搜索树