c++用new 创建一类对象数组时,指针对象的表示是怎么表示的。为什么访问pa指针对象函数方法和访问p1的不同
#include<iostream.h>classmycla{inta,b;public:voidsetxy(intx,inty){a=x;b=y;}mycla(){co...
#include <iostream.h>
class mycla
{
int a,b;
public:
void setxy(int x,int y)
{a=x;b=y;}
mycla()
{cout<<"constructor!\n";
a=0;b=0;
}
~mycla()
{cout<<"destructor!"<<"a="<<a<<",b="<<b<<endl;
}
void show ()
{cout<<"a="<<a<<",b="<<b<<endl;
}
};
void main()
{
mycla*pa=new mycla[3];
for(int i=0;i<3;i++)
pa[i].show();
mycla*p1=new mycla;
p1->setxy(66,88);
for(i=0;i<3;i++)
pa[i].setxy(i*i+1,i*i+1);
delete p1;
for (i=0;i<3;i++)
pa[i].show();
delete []pa;
}
为什么访问指针数组对象的成员函数时p1的用p1->成员函数 而pa指针直接用 pa[i].成员函数? pa[i]不是指针吗?怎么能取代对象?
指针对象访问对象成员函数不是用“指针->成员函数 ” 或者“*指针.成员函数”的表示吗?为什么pa指针不是这样子也可以通过编译? 展开
class mycla
{
int a,b;
public:
void setxy(int x,int y)
{a=x;b=y;}
mycla()
{cout<<"constructor!\n";
a=0;b=0;
}
~mycla()
{cout<<"destructor!"<<"a="<<a<<",b="<<b<<endl;
}
void show ()
{cout<<"a="<<a<<",b="<<b<<endl;
}
};
void main()
{
mycla*pa=new mycla[3];
for(int i=0;i<3;i++)
pa[i].show();
mycla*p1=new mycla;
p1->setxy(66,88);
for(i=0;i<3;i++)
pa[i].setxy(i*i+1,i*i+1);
delete p1;
for (i=0;i<3;i++)
pa[i].show();
delete []pa;
}
为什么访问指针数组对象的成员函数时p1的用p1->成员函数 而pa指针直接用 pa[i].成员函数? pa[i]不是指针吗?怎么能取代对象?
指针对象访问对象成员函数不是用“指针->成员函数 ” 或者“*指针.成员函数”的表示吗?为什么pa指针不是这样子也可以通过编译? 展开
展开全部
首先 这些问题你可以在<C和指针>这本书中找到 这么多字 还是这么晚 给个分吧。。。
其次 a->b 和 (*a).b 是一个意思 括号是养成良好习惯 你熟知运算符的优先级可以飘逸些。。
其中a 是一个指针 b是一个成员变量或者函数
下面要讲清这个问题非常复杂 以至于我还是推荐你直接看书的好。。。。
。。。。好吧 开始。。。。。
-------> mycla*pa=new mycla[3];
您定义了一个mycla类的对象的数组 对象的堆叠(请允许我这么说)是3次(个)
因为是数组,C(以及他的直接亲儿子C++)是这么来记录数组的:
数组在内存空间上是连续的 那么只要知道对象的类型(用于单个对象单元计算大小),对象的首地址(就是第1个(或者说第0个)对象的首地址),那么就能唯一确定这个数组的长度以及每个对象的位置
那么 pa就应当记录下mycla[3]的首地址 换句话说 这里的pa等于mycla[0]的首地址 也就是说pa=&mycla[0] 又因为上面提及C记录数组的方式,那么mycla这个数组名也代表数组的首地址(其实还包括了“个数"这个信息,以下会继续讲) 那么事实上 pa=mycla=&mycla[0] 这3个东西的”值“是一样的,只不错后2个是常量,pa是变量
------>pa[i].show();
自然pa是一个指向数组的指针,且指向的对象的类型也是事先声明的mycla,那么pa[i]就是*(pa+i)
注意 [ ] 这2个运算符包含了取值运算符*的功能。那么pa[i]就是pa这个指针经过+i后(每次+1指针实际指向的位置的增幅是有编译器根据你申明的类型所决定的,具体的大小是sizeof(mycla))指向了第i个对象,然后*做间接运算,取该地址下的内容。
-------->mycla*p1=new mycla;
这个p1所指向的内容--->不是<----一个数组,而是直接一个变量,那么p1直接做*运算就行了
换句话说 *p1就等于你new的那个对象
--------->p1->setxy(66,88);
这里的->是指针的另一种运算符 ->就等于*().这种用法 你用(*p1).setxy(66,88)是一样的
这是方便程序员的一种写法,让你的程序用指针的方式表达。
---------->pa[i].show(); 貌似你是对这个有问题?这个上面已经讲过了
---------->给你个例子 自己体会 mycla *pLycrus = new mycla[5];
我想调用第3个的set函数 可以这样写
1 *(pLycrus+3).set()
2 (pLycrus+3)->set()
3 pLycrus[3].set()
结论 你的问题在于你根本不了解C的指针和数组是怎么工作的
给你额外启发
sizeof(指针) 返回的是1个字节(或者是2个 或者是4的,实际情况参考你的OS是32或64位,以及编译器的行为。。)。
sizeof(数组名) 返回的是数组的实际大小(根据不同的架构会有不同,为什么过于复杂,不想牵扯)。
指针=数组名 (赋值) 那么 结论是 1. 数组名可以把首地址赋值给指针 但绝不等于指针(比如数组的个数信息等) 2.数组的工作方式是首地址+单个对象的sizeof(类或基本类型)。
再给你而外启发
2维数组的第1维实际保存的是第2维数组的首地址,不想具体解释了 自己去看《C和指针》这本书
你的不理解只是 不理解数组的[ ]运算符 和指针 * ->运算符,以前只是照葫芦画瓢,2个一起出现你就不理解了
你或许会问函数是如何工作的?其实函数名保存的是函数代码的入口地址(函数名是常量!!)。。。也就是说 有的时候你申明了f(int,int) 你调用f(a,b)和 *f(a,b)是一样的 编译器会自动把函数名和入口地址以及指向的函数转换的,只不过当你用到函数指针的时候,才会有差别
有个库函数是 qsort() 具体形式是
void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *,
const void *) ); buf是你指向一段内存区域的首地址, num是你要排序的对象的个数(基本类型也行,总之就是一个sizeof的事),后面那个compare是一个指向函数的指针 你看那个* 这就是具体的用法
好了 上面的*(pLycrus+3).set()的set()是一个函数,其实也是一个指针,只不过这个函数常指针指向了一个编译器分配给你的地址,然后自动执行了上面的函数的操作。。。他们是一样的。。。
其次 a->b 和 (*a).b 是一个意思 括号是养成良好习惯 你熟知运算符的优先级可以飘逸些。。
其中a 是一个指针 b是一个成员变量或者函数
下面要讲清这个问题非常复杂 以至于我还是推荐你直接看书的好。。。。
。。。。好吧 开始。。。。。
-------> mycla*pa=new mycla[3];
您定义了一个mycla类的对象的数组 对象的堆叠(请允许我这么说)是3次(个)
因为是数组,C(以及他的直接亲儿子C++)是这么来记录数组的:
数组在内存空间上是连续的 那么只要知道对象的类型(用于单个对象单元计算大小),对象的首地址(就是第1个(或者说第0个)对象的首地址),那么就能唯一确定这个数组的长度以及每个对象的位置
那么 pa就应当记录下mycla[3]的首地址 换句话说 这里的pa等于mycla[0]的首地址 也就是说pa=&mycla[0] 又因为上面提及C记录数组的方式,那么mycla这个数组名也代表数组的首地址(其实还包括了“个数"这个信息,以下会继续讲) 那么事实上 pa=mycla=&mycla[0] 这3个东西的”值“是一样的,只不错后2个是常量,pa是变量
------>pa[i].show();
自然pa是一个指向数组的指针,且指向的对象的类型也是事先声明的mycla,那么pa[i]就是*(pa+i)
注意 [ ] 这2个运算符包含了取值运算符*的功能。那么pa[i]就是pa这个指针经过+i后(每次+1指针实际指向的位置的增幅是有编译器根据你申明的类型所决定的,具体的大小是sizeof(mycla))指向了第i个对象,然后*做间接运算,取该地址下的内容。
-------->mycla*p1=new mycla;
这个p1所指向的内容--->不是<----一个数组,而是直接一个变量,那么p1直接做*运算就行了
换句话说 *p1就等于你new的那个对象
--------->p1->setxy(66,88);
这里的->是指针的另一种运算符 ->就等于*().这种用法 你用(*p1).setxy(66,88)是一样的
这是方便程序员的一种写法,让你的程序用指针的方式表达。
---------->pa[i].show(); 貌似你是对这个有问题?这个上面已经讲过了
---------->给你个例子 自己体会 mycla *pLycrus = new mycla[5];
我想调用第3个的set函数 可以这样写
1 *(pLycrus+3).set()
2 (pLycrus+3)->set()
3 pLycrus[3].set()
结论 你的问题在于你根本不了解C的指针和数组是怎么工作的
给你额外启发
sizeof(指针) 返回的是1个字节(或者是2个 或者是4的,实际情况参考你的OS是32或64位,以及编译器的行为。。)。
sizeof(数组名) 返回的是数组的实际大小(根据不同的架构会有不同,为什么过于复杂,不想牵扯)。
指针=数组名 (赋值) 那么 结论是 1. 数组名可以把首地址赋值给指针 但绝不等于指针(比如数组的个数信息等) 2.数组的工作方式是首地址+单个对象的sizeof(类或基本类型)。
再给你而外启发
2维数组的第1维实际保存的是第2维数组的首地址,不想具体解释了 自己去看《C和指针》这本书
你的不理解只是 不理解数组的[ ]运算符 和指针 * ->运算符,以前只是照葫芦画瓢,2个一起出现你就不理解了
你或许会问函数是如何工作的?其实函数名保存的是函数代码的入口地址(函数名是常量!!)。。。也就是说 有的时候你申明了f(int,int) 你调用f(a,b)和 *f(a,b)是一样的 编译器会自动把函数名和入口地址以及指向的函数转换的,只不过当你用到函数指针的时候,才会有差别
有个库函数是 qsort() 具体形式是
void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *,
const void *) ); buf是你指向一段内存区域的首地址, num是你要排序的对象的个数(基本类型也行,总之就是一个sizeof的事),后面那个compare是一个指向函数的指针 你看那个* 这就是具体的用法
好了 上面的*(pLycrus+3).set()的set()是一个函数,其实也是一个指针,只不过这个函数常指针指向了一个编译器分配给你的地址,然后自动执行了上面的函数的操作。。。他们是一样的。。。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询