我开始编写这段代码以获得乐趣,我很惊讶它编译和工作。 (我正在使用Dev C ++进行编译。)我想创建一个结构数组,但在创建数组之前,它存储和读取的值就像它已经是一个数组一样。为什么会这样,我怎么还能创建一个结构数组,以便跟踪数组的总大小?
#include <iostream>
using namespace std;
struct Shape
{
public:
int x,y,z;
};
struct Triangle: public Shape
{
public:
int tNum;
};
struct Rectangle: public Shape
{
public:
int rNum;
float differentNum;
};
struct Circle: public Shape
{
public:
int cNum;
};
int main(void)
{ int i;
Triangle tri;
Rectangle rec;
Circle cir;
Shape *arr[3]={&tri, &rec, &cir};
for(i=1;i<5;i++){ arr[1][i].x=i*2; cout<<"set tri["<<i<<"] "<<i*2<<endl;} cout<<endl;
for(i=1;i<5;i++){ arr[2][i].x=i*9; cout<<"set rec["<<i<<"] "<<i*9<<endl;} cout<<"-----------------"<<endl;
for(i=1;i<5;i++){ cout<<"read tri["<<i<<"] "<<arr[1][i].x<<endl;} cout<<endl;
for(i=1;i<5;i++){ cout<<"read rec["<<i<<"] "<<arr[2][i].x<<endl;}
system("pause");
return(0);
}
/*output
set tri[1] 2
set tri[2] 4
set tri[3] 6
set tri[4] 8
set rec[1] 9
set rec[2] 18
set rec[3] 27
set rec[4] 36
-----------------`
read tri[1] 2
read tri[2] 4
read tri[3] 6
read tri[4] 8
read rec[1] 9
read rec[2] 18
read rec[3] 27
read rec[4] 36*/
答案 0 :(得分:3)
您有一个包含3个Shape*
变量的数组,每个变量都指向堆栈中的有效Shape
实例:
arr[0]
指向tri
个实例,因此arr[0][0]
是tri
个实例。arr[1]
指向rec
个实例,因此arr[1][0]
是rec
个实例。arr[2]
指向cir
个实例,因此arr[2][0]
是cir
个实例。 arr
的任何其他用法基本上都是非法的(即使它可能有效)。
尽管不推荐,rec
实例和cir
实例紧接在tri
实例之后出现在堆栈中的事实允许您使用arr
在其他几个方面,“活着”:
arr[0][1]
是rec
实例,它出现在tri
实例之后的堆栈中。arr[0][2]
是cir
实例,它出现在rec
实例之后的堆栈中。arr[1][1]
是cir
实例,它出现在rec
实例之后的堆栈中。正如下面的一条评论所指出的,它实际上取决于堆栈的实现。
通过arr
访问内存的任何其他(不同)尝试都是潜在的内存访问冲突。
以下是您应该如何做的事情:
#include <string>
using namespace std;
class Shape
{
protected:
Shape() {}
virtual ~Shape() {}
string type;
int x,y,z;
public:
string GetType() const {return type;}
void SetX(int val) {x = val;}
void SetY(int val) {y = val;}
void SetZ(int val) {z = val;}
};
class Triangle : public Shape
{
public:
Triangle():type("Triangle") {}
void SetNum(int val) {tNum = val;}
private:
int tNum;
};
class Rectangle : public Shape
{
public:
Rectangle():type("Rectangle") {}
void SetNum(int val) {rNum = val;}
void SetDifferentNum(float val) {differentNum = val;}
private:
int rNum;
float differentNum;
};
class Circle : public Shape
{
public:
Circle():type("Circle") {}
void SetNum(int val) {cNum = val;}
private:
int cNum;
};
...
Triangle tri;
Rectangle rec;
Circle cir;
Shape* arr[3] = {&tri, &rec, &cir};
int size = sizeof(arr)/sizeof(*arr);
for (i=0; i<size; i++)
{
arr[i]->SetX(i*2);
cout << "set " << arr[i]->GetType() << "[" << i << "] = " << i*2 << endl;
}
答案 1 :(得分:0)
你有一些严重的未定义的行为在这里;你的代码没有做你认为它正在做的事情。例如,arr[2]
是指向cir
的指针,但arr[2][1]
和arr[2][2]
是指向未初始化的内存块的指针。根据您的定义
Shape *arr[3]={&tri, &rec, &cir};
您可以安全地访问arr[0]
(指向tri
的指针),arr[1]
(指向rec
的指针)和arr[2]
(指向{{的指针) 1}}),但那就是全部。