如何在c++中填充对象指针数组

How to fill an array of object pointers in C++?

本文关键字:对象 指针 数组 填充 c++      更新时间:2023-10-16

我正试图完成一个家庭作业来创建一个Shape类层次结构。在main()中,我试图填充一个指向Shape对象的指针数组。然后,在填充之后,我需要循环遍历该数组并在每个对象指针上调用print()(这里称为"SendToString")函数。

当运行这个时,它在运行时第二次for循环时崩溃,就在我输入一些形状然后输入'done'之后。它似乎不能循环通过shape_array?

在getShape()中,如果用户在控制台上输入'done',则返回NULL指针。当getShape()返回NULL指针时,main()中的循环应该退出并停止填充数组。

我的代码有什么问题?我梳理了好几个小时,还是没发现问题所在。谢谢。

#include "stdafx.h"
#include <iostream>
#include "Shape.h"
#include <string>
using namespace std;
Shape* getShape();
int main()
{
    int i; //fill the shape array.
    int j; //loop through the shape array.
    string output;
    Shape* shape_array[15]; //array of base Shape pointers
    Shape *shape_ptr;
    int nElements = sizeof(shape_array) / sizeof(shape_array[0]);
    cout << "Enter a list of shapes - 'done' to end" << endl;
    //fill the array of shape object pointers
    for (i =0; i <= nElements; i++) { //loop through the defined array of 15 elements
        shape_ptr = getShape(); //return a shape ptr or NULL ptr
        if (shape_ptr== NULL) 
        {
            break; //stop filling the array (stop calling getShape)
        }
        else
        {
            shape_array[i]= shape_ptr; //add the shape pointer
        }
    } //end for
    cout << "The list of shapes entered..." << endl;
    for (j = 0; j < nElements; j++) {
        output = shape_array[j]->SendToString();
        cout << output << endl;
    } 
    return 0;
} //end main

下面是输出:

Enter a list of shapes - 'done' to end
Enter the shape's color (or 'done')...
green
Enter shape type...
circle
Enter the radius...
5.0
Enter the shape's color (or 'done')...
red
Enter shape type...
circle
Enter the radius...
4.0
Enter the shape's color (or 'done')...
done
User entered done!
The list of shapes entered...
green circle with a radius of 5 and area of 78

它不能打印第二个对象并在那里崩溃

就像juanchopanza在他的评论中说的,你正在越界访问数组。

for (j = 0; j <= nElements; j++) {
应:

for (j = 0; j < nElements; j++) {

如果我定义一个大小为2的数组,如:

int i[2];

那么我可以用I[0]访问第一个元素,用I[1]访问第二个元素。这是所有访问过的2个元素,我还没有访问过I[2]。C/c++数组中可接受的索引范围始终是0到(elements -1)。

看到这个:http://www.cplusplus.com/doc/tutorial/arrays/

还请注意,在最后一个循环中,当您没有为数组中的所有15个点输入形状时,您将遍历整个数组。这将导致您尝试访问由垃圾指针指向的内存,因此可能会取消映射。这很可能是导致崩溃的原因。

除了在第一个循环中明显的越界访问外,处理整个数组时,就好像它的所有元素都指向有效对象:

for (j = 0; j < nElements; j++) {
    output = shape_array[j]->SendToString();

但是不能保证它们是正确的,因为你只能在getShape()返回第一个NULL之前设置元素,否则你就会因为你奇怪的循环技术而使元素未设置,你可以这样做:

for (i =0; i < nElements; i++)
{
  shape_array[i]= something_good;
  i++;  // LOOK! Index increased one extra time per loop!!!
}

在第一个循环中,只设置数组中的第二个元素,但对它们全部取消引用。您正在取消引用无效指针。如果您要编写这种代码,您应该学习使用调试器。

首先,数组索引的有效范围是[0, nElements - 1],其次,两个循环都写错了,包含错误。例如,在第一个循环中,变量i递增两次。

正确的代码应该如下所示

#include "stdafx.h"
#include <iostream>
#include <string>
#include "Shape.h"
Shape *getShape(); // Why this function is declared here but not is defined in the module?!
int main()
{
    const int N = 15;
    Shape* shape_array[N]; //array of base Shape pointers

    std::cout << "Enter a list of shapes - 'done' to end" << std::endl;
    //fill the array of shape object pointers
    Shape *shape_ptr;
    int nElements = 0;
    for ( ; nElements < N && ( shape_ptr = getShape() ); nElements++ ) 
    { 
        //loop through the defined array of 15 elements
        shape_array[nElements] = shape_ptr; //add the shape pointer
    } //end for
    std::cout << "The list of shapes entered..." << std::endl;
    for ( int i = 0; i < nElements; i++ ) 
    {
        std::string output = shape_array[i]->SendToString();
        std::cout << output << std::endl;
    } 
    return 0;
}