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

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;
}
...全文
151 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;
}
下载前必看:https://pan.quark.cn/s/a4b39357ea24 C/C++语言将二维数组作为参数传递容易使人迷惑且易出错,本文将常用的几种方法列出,以方便用时查阅。 三种方法总结如下(GCC验证成功): 方法一:形参为二维数组并给定第二维长度 此方法是简单直观的方法,形参与实参一样,容易理解。 举例: #include void subfun(int n, char subargs[][5]) { int i; for (i = 0; i < n; i++) { printf("subargs[%d] = %s", i, subargs[i]); } } 在C/C++编程,二维数组的处理是一个重要的概念,特别是在处理矩阵或表格数据时。 在函数调用,二维数组的传递方式可以有多种,每种方式都有其适用场景和注意事项。 以下是对标题和描述提及的三种方法的详细说明:### 方法一:形参为二维数组并给定第二维长度这种方法是最直观且易于理解的。 在函数声明,形参被声明为一个二维数组,并且指定第二维的长度。 例如:```cvoid subfun(int n, char subargs[][5]) { // ...}```这里的`subargs`实际上是一个行指针数组,每个元素都是一个指向字符数组的指针。 在调用时,实参是一个与形参匹配的二维数组,如`char args[][5]`。 ```cchar args[][5] = {"abc", "def", "ghi"};subfun(3, args);```函数内部可以通过`subargs[i]`访问每一行的数据。 ### 方法二:形参为指向数组的指...

65,209

社区成员

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

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