把“类数组”作为参数传递,迷惑中...

Microsues 2011-06-08 09:35:53
问一下,下面代码中,f(Base* pb,int sz)函数里,执行for循环时为什么会出错?
#include<iostream>
using namespace std;

struct Base{
virtual void fun() {cout<<"Base::fun()"<<endl;}
};

struct Derived: Base{
void fun() {cout<<"Derived::fun()"<<endl;}
//private:
// int x;
};

void f(Base* pb,int sz)
{
for(int i=0;i<sz;++i)
pb[sz].fun();
}
int main()
{
if(sizeof(Base) == sizeof(Derived))
{
cout<<"equal\n";
}
Base b[3];
//b[1].fun();
Derived d[3];
Derived dd[5];
f(b,3);
f(d,3); //因为数组名被转化成指针,所以调用f()时,把Derived*--> Base*
cout<<"f(dd,5)\n";
f(dd,5);
return 0;
}
...全文
133 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq120848369 2011-06-08
  • 打赏
  • 举报
回复
偏移量有问题,而且根本没有多态了。
蓝染忽右介 2011-06-08
  • 打赏
  • 举报
回复
void f(Base* pb,int sz)
{
for(int i=0;i<sz;++i)
pb[i].fun();//here
}
Microsues 2011-06-08
  • 打赏
  • 举报
回复
能不能详细解释一下:“是用Base的步长解 Derived 数组”?
[Quote=引用 8 楼 ljt3969636 的回复:]

这个i++和++i是一样的。另外如dizuo和pengzhixi,所说。
这个如果是单纯保证每个元素都是值传递,而每个都被正确截断..那危害还小些呢!但是LZ您现在是用Base的步长解 Derived 数组,全乱了...
[/Quote]
Microsues 2011-06-08
  • 打赏
  • 举报
回复
不好意思啊,for循环里应该是pb[i],我的问题是当把Derived对象传给f的时候,第二次for循环为什么报错?有接受说是偏移量不一样,能不能详细些?
#include<iostream>
using namespace std;

struct Base{
virtual void fun() {cout<<"Base::fun()"<<endl;}
};

struct Derived: Base{
void fun() {cout<<"Derived::fun()"<<endl;}
private:
int x;
};

void f(Base* pb,int sz)
{
for(int i=0;i<sz;++i)
pb[i].fun();
}
int main()
{
if(sizeof(Base) == sizeof(Derived))
{
cout<<"equal\n";
}
Base b[3];
//b[1].fun();
Derived d[3];
Derived dd[5];
f(b,3);
f(d,3); //因为数组名被转化成指针,所以调用f()时,把Derived*--> Base*
cout<<"f(dd,5)\n";
f(dd,5);
return 0;
}
binggou8993 2011-06-08
  • 打赏
  • 举报
回复
传参时,需要将Derived指针强制转换为Base的指针,否则编译不过
如果强制转换,就会出现被截断的显现,但是在本例中不会出现这种现象
因为基类和派生类都没有多余的成员
ljt3969636 2011-06-08
  • 打赏
  • 举报
回复
这个i++和++i是一样的。另外如dizuo和pengzhixi,所说。
这个如果是单纯保证每个元素都是值传递,而每个都被正确截断..那危害还小些呢!但是LZ您现在是用Base的步长解 Derived 数组,全乱了...
ryfdizuo 2011-06-08
  • 打赏
  • 举报
回复
http://www2.research.att.com/~bs/bs_faq2.html
Memory下:what is wrong with array?
pengzhixi 2011-06-08
  • 打赏
  • 举报
回复
因为不能对数组玩多态。
ryfdizuo 2011-06-08
  • 打赏
  • 举报
回复
lz 你这么传根本就是错的,放弃吧。
bdmh 2011-06-08
  • 打赏
  • 举报
回复
for(int i=0;i<sz;++i)
为什么用前置 ++i,呢,这样会先改变i,然后进行操作,有越界危险
改成,后置++
for(int i=0;i<sz;i++)
ryfdizuo 2011-06-08
  • 打赏
  • 举报
回复
void f(Base* pb,int sz)
{
for(int i=0;i<sz;++i)
pb[i].fun();
}

低级错误。
PS:lz啊,将 Derived dd[5];派生类 对象数组传给f函数问题很大。。。。
f函数调用pf[i]的时候会根据sizeof(Base)截断dd的。你自己体会一下。
KID_coder 2011-06-08
  • 打赏
  • 举报
回复

#include<iostream>
using namespace std;

struct Base{
virtual void fun() {cout<<"Base::fun()"<<endl;}
};

struct Derived: Base{
void fun() {cout<<"Derived::fun()"<<endl;}
//private:
// int x;
};

void f(Base* pb,int sz)
{
for(int i=0;i<sz;++i)
pb[i].fun(); //注意越界
}
int main()
{
if(sizeof(Base) == sizeof(Derived))
{
cout<<"equal\n";
}
Base b[3];
//b[1].fun();
Derived d[3];
Derived dd[5];
f(b,3);
f(d,3); //因为数组名被转化成指针,所以调用f()时,把Derived*--> Base*
cout<<"f(dd,5)\n";
f(dd,5);
return 0;
}
ljt3969636 2011-06-08
  • 打赏
  • 举报
回复
for(int i=0;i<sz;++i)
pb[sz].fun();//你要 pb[i].fun();吧?下标sz已经越界了
Louistao 2011-06-08
  • 打赏
  • 举报
回复
马克 学习
ljt3969636 2011-06-08
  • 打赏
  • 举报
回复
LZ的你代码修正了越界之后,应该不至于报错,但是这是因为你的两个类都是空的其尺寸恰好都等于一个虚表指针的大小。



struct Base{
Base():i(1){}
int i;
};

struct Derived: Base{
Derived():i(2){}
int i;
};

int main()
{

Base b[5];
Derived d[5];
for(int i=0;i<5;++i)
{
b[i]=d[i];//虽然也不怎么样~~但是好歹在值上截断了
}

for(int i=0;i<5;++i)

cout<<b[i].i<<endl;//输出的都是基类的i值1

cout<<"------------------"<<endl;
Base*p=d;//你的例子相当于这样
for(int i=0;i<5;++i)

cout<<p[i].i<<endl;//输出1和2相间的数字,为什么?注意此时sizeof(Base)=4;而sizeof(Derived)=8

return 0;
}

64,652

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧