为什么这个程序会创建这样的输出?

时间:2014-07-25 14:51:58

标签: c++ arrays output

为什么这个程序会写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;
}

静态数组B arrB[N]和D arrD[N]似乎在这里引起了麻烦。

4 个答案:

答案 0 :(得分:9)

阵列不是多态的;只有在需要单个元素时,才能将D*传递给期望B*的函数。 (尝试使用std::vector,你会得到一个编译时错误。)原因很简单:访问数组元素所需的指针算法是基于指向元素的静态大小,所以每次你在i++的循环中执行sum1,然后编制索引,编译器将元素的地址计算为arr + i * sizeof(B)(在机器级别,arr是纯的,无类型地址)。

当静态类型与动态类型不同时,尝试进行指针运算是未定义的行为,因此就语言而言,任何事情都可能发生。

这是使用C样式数组的另一个原因。

答案 1 :(得分:6)

问题是数组不包含指向对象的指针而是包含整个对象的指针。 因此,当您通过指向基类的指针使用D数组时(如James所述),行为未定义。

在大多数系统中实际上可能会发生什么:基于指针的循环只迭代D对象的一半,因为B对象只包含一个int,而D对象包含其中两个。

因此循环只查看前5个D对象:

b / d
10/11
11/12
12/13
13/14
14/15

总计不祥的125。

答案 2 :(得分:1)

我认为将D数组转换为B数组是不正确的。步幅不正确。这就是为什么你会看到这些重复的价值观。

答案 3 :(得分:0)

运行以下代码,您将知道原因

    #include <iostream>
using namespace std;

class B{
public:
    B(): b(bCounter++){
        cout<<"B called\n";
        }
    int b;
    static int bCounter;
};

int B::bCounter = 0;

class D : public B{
public:
    D() : d(bCounter){
        cout<<"D called\n";
        }
    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++)
    { 
        cout<<arr[i].b<<"\n";
        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;
}
相关问题