C++ 行为类似于结构数组,但不声明数组

C++ 行为类似于结构数组,但不声明数组,c++,arrays,class,struct,output,C++,Arrays,Class,Struct,Output,我开始写这段代码是为了好玩,我对它的编译和运行感到惊讶。(我使用DEV C++编译)我想创建一个结构数组,但是在创建数组之前,它存储并读取值,就像它已经是数组一样。为什么会这样?我如何创建一个结构数组以便跟踪数组的总大小 #include <iostream> using namespace std; struct Shape { public: int x,y,z; }; struct Triangle: public Shape { public: int tNum;

我开始写这段代码是为了好玩,我对它的编译和运行感到惊讶。(我使用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*/
#包括
使用名称空间std;
结构形状
{
公众:
int x,y,z;
};
结构三角形:公共形状
{
公众:
内特努姆;
};
结构矩形:公共形状
{
公众:
内部;
浮动差分法;
};
结构圆:公共形状
{
公众:
国际cNum;
}; 
内部主(空)
{int i;
三角三;
矩形rec;
圆cir;
形状*arr[3]={&tri,&rec,&cir};

对于(i=1;i您有一个由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;
}
#包括
使用名称空间std;
阶级形态
{
受保护的:
形状(){}
虚拟~Shape(){}
字符串类型;
int x,y,z;
公众:
字符串GetType()常量{return type;}
void SetX(int val){x=val;}
void SetY(int val){y=val;}
void SetZ(int val){z=val;}
};
类三角形:公共形状
{
公众:
三角形():键入(“三角形”){}
void SetNum(int val){tNum=val;}
私人:
内特努姆;
};
类矩形:公共形状
{
公众:
矩形():键入(“矩形”){}
void SetNum(int val){rNum=val;}
void SetDifferentNum(float val){differentNum=val;}
私人:
内部;
浮动差分法;
};
班级圈子:公共形态
{
公众:
Circle():键入(“Circle”){}
void SetNum(int val){cNum=val;}
私人:
国际cNum;
};
...
三角三;
矩形rec;
圆cir;
形状*arr[3]={&tri,&rec,&cir};
int size=sizeof(arr)/sizeof(*arr);
对于(i=0;iSetX(i*2);

cout您有一个由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;
}
#包括
使用名称空间std;
阶级形态
{
受保护的:
形状(){}
虚拟~Shape(){}
字符串类型;
int x,y,z;
公众:
字符串GetType()常量{return type;}
void SetX(int val){x=val;}
void SetY(int val){y=val;}
void SetZ(int val){z=val;}
};
类三角形:公共形状
{
公众:
三角形():键入(“三角形”){}
void SetNum(int val){tNum=val;}
私人:
内特努姆;
};
类矩形:公共形状
{
公众:
矩形():键入(“矩形”){}
void SetNum(int val){rNum=val;}
void SetDifferentNum(float val){differentNum=val;}
私人:
内部;
浮动差分法;
};
班级圈子:公共形态
{
公众:
Circle():键入(“Circle”){}
void SetNum(int val){cNum=val;}
私人:
国际cNum;
};
...
三角三;
矩形rec;
圆cir;
形状*arr[3]={&tri,&rec,&cir};
int size=sizeof(arr)/sizeof(*arr);
对于(i=0;iSetX(i*2);

cout您有一个由3个
Shape*
变量组成的数组,每个变量都指向堆栈中的一个有效
Shape
实例: