массивы классов, суммы, индексы и вычисления

Код:

class B {
public:
B () : b(++bCounter) {}
int b;
static int bCounter;
};

int B::bCounter = 0;

class D : public B {
public:
D () : d(0) {}
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;
}

Вопрос:

Что они возвращают:

1) sum1(arrB)знак равно

2) sum1(arrD)знак равно

3) sum2(arrD)знак равно

Когда я компилирую & запустить их, я получаю 55, 65 и 155, и понятия не имею, почему. Я понимаю, что в arrB переменные b = 1,2,3, …, 10, а в arrD b = 11,12, …, 20, поэтому я бы ответил на sum1 (arrB) = 55 и sum1 (arrD) = 155, как в сумме 11 + 12 + .. + 20, и sum2 (arrD) = 155, потому что везде d = 0.

Что я делаю неправильно?

1

Решение

Вы получаете нарезку объектов.
Вы передаете D* массив в функцию, которая принимает B* массив. D изначально больше чем B,

Каждый раз, когда вы делаете s+=arr[i].b; вы двигаете указатель по размеру B, в то время как вам нужно переместить его по размеру D, поэтому после каждой итерации указатель не перемещается ни на один элемент вперед.

[TheBPart|TheDPart][TheBPart|TheDPart][TheBPart|TheDPart]
^
|
iteration 0

[TheBPart|TheDPart][TheBPart|TheDPart][TheBPart|TheDPart]
^
|
iteration 1

[TheBPart|TheDPart][TheBPart|TheDPart][TheBPart|TheDPart]
^
|
iteration 2

[TheBPart|TheDPart][TheBPart|TheDPart][TheBPart|TheDPart]
^
|
iteration 3

Что происходит в вашем конкретном случае, так это то, что после каждой нечетной итерации он указывает где-то в средний объекта D учебный класс. Это происходит только потому, что D ровно вдвое больше, чем Bиначе поведение было бы другим.

4

Другие решения

Проблема заключается в преобразовании arrD в arrB, B имеет размер 4 байта, в то время как D имеет размер 8 байтов.

Когда вы конвертируете D * в B *, вы фактически перепрыгиваете в памяти 4 байта за итерацию, а не 8 байтов. arrD будет хранить следующие значения в памяти, если мы берем 4 байта за раз

11   // arrD[0].b
0    // arrD[0].d
12   // arrD[1].b
0    // arrD[1].d
13   // arrD[2].b
0    // arrD[2].d
14   // arrD[3].b
0    // arrD[3].d
15   // arrD[4].b
0    // arrD[4].d
16   // arrD[5].b
0    // arrD[5].d
17   // arrD[6].b
0    // arrD[6].d
18   // arrD[7].b
0    // arrD[7].d
19   // arrD[8].b
0    // arrD[8].d
20   // arrD[9].b
0    // arrD[9].d

Теперь, когда вы суммируете 4 байта за раз, вы берете первые 10 значений этого. Следовательно, ваш результат: 11 + 0 + 12 + 0 + 13 + 0 + 14 + 0 + 15 + 0 = 65

Из аналогичных рассуждений вы можете узнать причину своего результата для sum2,

2