运行时多态性 - 箭头运算符访问错误的成员?
Posted
技术标签:
【中文标题】运行时多态性 - 箭头运算符访问错误的成员?【英文标题】:Runtime Polymorphism - Arrow operator accessing the wrong member? 【发布时间】:2020-05-18 08:00:57 【问题描述】:我的程序中有以下课程:
class base
public:
int bval;
base()
bval = 1;
;
class deri: public base
int dval;
public:
deri()
dval = 2;
;
还有一个函数f
,它接受指向base
类对象的指针和它指向的数组的大小:
void f(base *arr, int size)
for(int i=0; i<size; i++, arr++)
cout << arr->bval << " ";
cout << endl;
这是主要的:
int main()
base a[5];
f(a, 5); // first call
deri b[5];
f(b, 5); // second call
第一次调用的输出是1 1 1 1 1
,这是正确的。
但是第二次调用的输出是1 2 1 2 1
,这让我很意外。对于函数f
内的for
循环的每第二次迭代,似乎dval
的值将代替bval
打印。
此外,如果我在 deri
类中包含另一个私有数据成员 int dval2
,则每次执行第二次调用时都会输出 1 2 65535 1 2
(因此 65535 看起来不像任何随机值)。
为什么箭头操作符会出现这种行为?
【问题讨论】:
您将指针作为base
指针传递,因此指针算法不适合您的deri
数组。
对不起,我误读了这个问题。我已经编辑了我的评论。我仍然建议使用 std::vector 并让 f() 取一个const std::vector<deri>&
。
@ypnos 如果您能解释指针运算作为答案,我将不胜感激。
【参考方案1】:
您将指针作为base
指针传递给f()
,因此指针算法不适合您的deri
数组。
此时:for(int i=0; i<size; i++, arr++)
,只有base
的大小被添加到arr
,因为arr
是一个base
指针。
在这种情况下,真正存储什么类型的对象并不重要;增加指针值时不查看它们。
两个有帮助的选项:
-
使用 C++ 容器。例如。
std::vector<deri> b(5)
和 void f(const std::vector<deri> &vec)
。
传递一个指针数组。在这种情况下,当使用箭头运算符访问指针时,可能会发生多态性。请注意,您的基类需要一个 vtable
,您可以通过定义和声明一个虚拟析构函数来获得它(不需要 vtable 来提供预期的输出,但有几个其他原因)。
【讨论】:
即使我们指定了名称,成员是否在后台通过指针运算访问? 会员权限不是你的问题,是循环出错了! @KashinathPatekar,因为 Base* 在编译时被绑定以上是关于运行时多态性 - 箭头运算符访问错误的成员?的主要内容,如果未能解决你的问题,请参考以下文章