充当结构数组而不声明数组
Acts like an array of structs without declaring array
我开始写这段代码是为了好玩,我很惊讶它编译和工作。(我正在使用开发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*/
您有一个包含 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;
}
你在这里发生了一些严重的未定义的行为;你的代码没有做你可能认为它正在做的事情。 例如,arr[2]
是指向cir
的指针,但arr[2][1]
和arr[2][2]
是指向未初始化内存块的指针。 从您的定义
Shape *arr[3]={&tri, &rec, &cir};
您可以安全地访问arr[0]
(指向tri
的指针)、arr[1]
(指向rec
的指针)和arr[2]
(指向cir
的指针),但仅此而已。
相关文章:
- 无法将字符串数组声明为类成员而不是字符 (C++)
- 为什么从函数返回数组时需要将数组声明为静态数组.(C++)
- 在 c++ 中直接访问的内联数组声明
- 由于 2D 数组声明,C++ 14 中的运行时错误
- 如何将char数组声明为函数参数?或告诉我此代码中还有其他问题?
- 来自函数参数的 C++ 静态数组声明
- C++ 中的动态数组声明
- C++数组声明
- 数组声明中的错误:表达式必须具有常量值
- 程序随数组声明崩溃
- 运行时和编译时的数组声明
- C++数组声明和初始化
- 带有常量表达式的数组声明
- C ,数组声明,模板,链接器错误
- 如何用'n'维数组声明 std::vector?
- 数组声明上的编译器错误
- 这是什么数组声明
- 头文件类中的数组声明
- 节点数组声明
- 在静态数组声明中使用了两次C++常量