[英]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.