为什么这个程序会写45,125和300?我知道45和300,我对一个案例sum1(arrD)更感兴趣,程序写入125.我希望有人知道.
#include <iostream>
using namespace std;
class B{
public:
B(): b(bCounter++){}
int b;
static int bCounter;
};
int B::bCounter = 0;
class D : public B{
public:
D() : d(bCounter){}
int d;
};
const int N = 10;
B arrB[N];
D arrD[N];
int sum1(B* arr){
int s = 0;
for (int i=0; i<N; i++) s+=arr[i].b;
return s;
}
int sum2 (D* arr){
int s = 0;
for (int i = 0; i<N; i++) s+= arr[i].b + arr[i].d;
return s;
}
int main(){
cout<<" result is: "<<sum1(arrB)<<endl;
cout<<" result is: "<<sum1(arrD)<<endl;
cout<<" result is: "<<sum2(arrD)<<endl;
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
静态数组B arrB[N]和D arrD[N]似乎在这里引起了麻烦.
数组不是多态的; 你可以将一个D*函数传递给一个函数,B*只要它期望一个元素.(尝试使用std::vector,你会得到一个编译时错误.)原因很简单:访问数组元素所需的指针算法是基于指向元素的静态大小,所以每次你i++在循环中做sum1然后索引,编译器计算元素的地址arr + i * sizeof(B)(在机器级别,其中arr是纯粹的无类型地址).
当静态类型与动态类型不同时,尝试进行指针运算是未定义的行为,因此就语言而言,任何事情都可能发生.
这是不使用C风格数组的另一个原因.
问题是数组不包含指向对象的指针而是包含整个对象的指针.因此,当您通过指向基类的指针使用D数组时(如James所述),行为未定义.
实际上在大多数系统中可能会发生什么:基于指针的循环只迭代D对象的一半以上,因为B对象只包含一个int,而D对象包含其中两个.
所以循环只查看前5个D对象:
b / d
10/11
11/12
12/13
13/14
14/15
Run Code Online (Sandbox Code Playgroud)
总计不祥的125.
| 归档时间: |
|
| 查看次数: |
125 次 |
| 最近记录: |