使用 -> 从对象索引数组访问虚函数

using -> to access a virtual function from an array of objects indices

本文关键字:数组 索引 访问 函数 对象 gt 使用      更新时间:2023-10-16

我目前正在编写一个专注于继承属性的c++赋值。

有一个基础类枪{},以及几个派生类:

手枪:公共枪支{}

左轮手枪:公共手枪{}

手枪:公共手枪{}

根据当前的赋值,我向这些类中的每个类添加了一个虚拟函数print(),该函数覆盖了前一个类的print()并添加了要打印的唯一变量。例如,枪有字符串制造商,手枪有字符串握把和手枪有布尔半自动

现在,我的教授想让我制作一个包含2(两)个物体的数组,一个是左轮手枪类型的物体:公共手枪,一个手枪类型的对象:公共手枪

在任务中,他说我们必须使用这个确切的代码来打印数组的内容:

for(int i=0; i <= numGuns; i++)
       **gunCabinet[i]->print();**

现在,我的代码。有问题的错误用粗体显示,就在底部附近。

int main() {
//declares the revolver and pistol objects
revolver Anaconda;
pistol M9;
//sets appropriate variables for the objects
Anaconda.setManufacturer("Smith & Wesson");
M9.setManufacturer("Beretta");
Anaconda.setCaliber(".44 special");
M9.setCaliber("9x19mm Parabellum");
Anaconda.setGrips("Hogue grips");
M9.setGrips("U.S. Military specification grips");
Anaconda.setSights("6x scope");
M9.setSights("U.S. Military specification iron sights");
Anaconda.setLaser(true);
M9.setLaser(false);
Anaconda.setSingleAction(true);
Anaconda.setNumberOfRounds(6);
M9.setSemiAuto(true);
 int numGuns = 2;
 gun* gunCabinet;
 gunCabinet = new gun[numGuns];
 gunCabinet[0] = Anaconda;
 gunCabinet[1] = M9;
 // *(gunCabinet) = Anaconda;
 //*(gunCabinet + 1) = M9;

//gun * gunCabinet[/*numGuns*/2] = {&Anaconda, &M9};


for(int i=0; i <= numGuns; i++)
   **gunCabinet[i]->print(); //ERROR ON THIS LINE**
//cout << Anaconda << endl;
//Anaconda.print();
//cout << M9 << endl;
//M9.print();

return 0;
}

我已经评论了我为实现这一目标所做的其他尝试。

现在,当我运行这个时,我得到一个错误,说"'->'的基操作数具有非指针类型'gun'"。

除非我的教授犯了错误,否则我想这件事全是我的错。问题是,我不明白自己做错了什么。我不一定在寻找作业的答案,相反,他的代码有效吗?如果它是有效的,我能对我做错了什么有一些建议吗(不是双关语)?非常感谢!

您将gunCabinet创建为gun对象的数组,但您真正想要的是gun*gun指针)的数组。

gun* gunCabinet[2];
gunCabinet[0] = &Anaconda;
gunCabinet[1] = &M9;

为了使用->,您需要从指针类型调用。当您使用数组访问时,您正在取消引用一个指针,因此您的错误是它是非指针类型。

您需要做的是拥有一个gun **gunCabinet,并使用每个堆栈变量的地址初始化数组,然后可以在数组访问中使用箭头运算符。

gun** gunCabinet;
gunCabinet = new gun*[numGuns];
gunCabinet[0] = &Anaconda;
gunCabinet[1] = &M9;

然后你可以使用

gunCabinet[0]->print();

稍后。

->运算符与指针一起使用,用于访问方法和成员。指针需要获取对象的地址。

因此,因为你有一个实际对象的数组,而不是指针的数组,所以你需要获得对它们地址的引用
您可以使用&运算符。

gun = &gunCabinet[1];
gun->A_Guns_method();

这只是一个想法,但。。。讲师给出的for循环中的行是**gunCabinet[i]->print();**(至少在你引用它的时候是这样)。在您的循环中,您已经编写了**gunCabinet[i]->print();。我怀疑表达式之前和之后的**都是为了强调,而不是实际代码的一部分。(后面的不可能。)如果没有它们,只需像Platinum Azure所建议的那样创建一组指针就足够了。而且是必要的,无论您使用什么表达式来访问它们,因为数组不能容纳多态对象;如果您试图将具有派生类型的东西放入基数组中,它将被切片,您将得到的只是基部分的副本。(一般来说,赋值不能很好地处理多态性,我通常建议通过从boost::noncopyable派生来使基类不可移植。)