繁体   English   中英

具有基本结构的结构数组返回错误的答案

[英]Array of structs with base struct returns wrong answer

我的代码给出了错误的答案,因此我将其范围缩小了。 当我的变量arrayCounter = 0时,它将在数组中返回正确的答案。 但是,当arrayCounter = 1时,我得到的错误答案为0。

#include <iostream>
using namespace std;

struct base
{
  int x,y;
};

struct myStruct : base
{
  char c;
  int numOne;
}; myStruct MS[10]; //array of myStruct

base * returnArray(char c)  //function that returns array type
{
  if(c=='m'){ return MS;}
  //I plan to have other structs here similar to myStruct.
}

int main()
{
  MS[0].x=204;   //init 0 value in array
  MS[1].x=97;    //init 1 value in array

  int arrayCounter=0; //count through array. if=0, returns correctly. If=1, then not correct...
  cout<<returnArray('m')[arrayCounter].x<<endl; //MS[1].x=204, MS[1].x=0

  system("pause");
}

指针算术(包括索引到数组中)是静态的。 它不知道您正在访问的对象的动态类型 这样,如果您使用指向派生对象数组的基本指针,并尝试递增该指针,则将遇到问题,因为指针算法假定所指向的对象确实基本对象。

如果您确实想要数组具有多态行为,则必须使用一个指针数组 ,并使returnArray函数返回base**

问题是sizeof(Base)= 8,当arrayCounter在returnArray('m')[arrayCounter]中从0增加到1时,地址更改为8,但sizeof(myStruct)= 16,则地址更改为MS [0 ]移至MS [1],如代码所示

如果您希望发生这种情况,可以更改指针类型

cout<<((myStruct*)returnArray('m'))[arrayCounter].x<<endl;

下面的代码列表输出:

address of base* array index 0: 0x6013c0
address of base* array index 1: 0x6013c8
address of MS array index 0: 0x6013c0
address of MS array index 1: 0x6013d0
97

#include <iostream>
#include <stdio.h>
using namespace std;

struct base
{
  int x,y;
};

struct myStruct : base
{
  char c;
  int numOne;
}; myStruct MS[10]; //array of myStruct

base * returnArray(char c)  //function that returns array type
{
  if(c=='m'){ return MS;}
  //I plan to have other structs here similar to myStruct.
}

int main()
{
  MS[0].x=204;   //init 0 value in array
  MS[1].x=97;    //init 1 value in array

  int arrayCounter=1; //count through array. if=0, returns correctly. If=1, then not correct...
  printf("address of base* array index 0: %p\n",&returnArray('m')[0]);
  printf("address of base* array index 1: %p\n",&returnArray('m')[1]);

  printf("address of MS array index 0: %p\n",&MS[0]);
  printf("address of MS array index 1: %p\n",&MS[1]);
  cout<<((myStruct*)returnArray('m'))[arrayCounter].x<<endl; //MS[1].x=204, MS[1].x=0

  return 0;
}

因为您的函数returnArray()返回base组,而operator []实际上根据元素大小smth计算偏移量,如下所示:

template<typename T>
T& operator [](T* array, size_t index)
{
  *(array + sizeof(T) * index);
}

因此,当您传递base数组时,此运算符会将其大小计算为sizeof(int) + sizeof(int) 多态仅适用于指针。 这样就可以像myStruct* a[10]也可以只返回myStruct的数组: myStruct* returnArray();

还有一件事。 如果最终您将创建一个比myStruct更大的派生类,并尝试将其存储在数组中,那么您将成功,但是将存储的对象将缩小到适合myStruct的大小,并且将丢失数据。

myStruct* returnArray(char c)将解决您当前的问题。 但是,如果您想在代码中使用许多派生类,您仍然会感到困惑。

以下代码可能是更好的选择:

struct Base
{
    int x,y;
    int get_x(){
        return x;
    }
}

cout << MS[arrayCounter].get_x() << endl;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM