c++ - 派生类的一些问题

标签 c++ arrays class oop object

<分区>

我正在尝试实现下面的函数和类,但是 arr[i].x 的输出是错误的。我正确地得到了 arr[0].x = 0 和 arr[1].x = 0,但是 arr[2].x 没有返回 0。有什么想法吗?

class Base {
public:
  int x;
};

class Derived : public Base {
public:
int y;
void init(Base *b);
void foo();
};

void Derived :: init(Base *b) {
  for( int i = 0; i < 3; ++i) {
    b[i].x = 0;
  }
}

void Derived :: foo() { 
  Derived arr[3];
  init(arr);
  for( int i = 0; i < 3; ++i) {
  cout<<"b["<<i<<"] "<<arr[i].x;
  }
}


int main()
{
    Derived der;
    der.foo();
    return 0;
}

最佳答案

void Derived :: foo() { 
    Derived arr[3];
    init(arr);

指向Derived 的指针Derived* 被传递给函数init(Base *b)。接下来发生的是,您的函数不会移动表中的 sizeof(Derived)=8,而是移动 sizeof(Base)=4,这会导致 的初始化code>x 数组中第一个和第二个 Derived 的成员以及第一个 Derivedy 成员,但不是 x 最后一个 Derived

Pointer arithmetic is done based on the size of the type of the pointer

考虑这个内存布局(在 x64 上):

在派生::foo()中:

Derived arr[3];

0x7fffffffe310  // 1st Derived, also address of arr[0].x
+8 = 
0x7fffffffe318  // 2nd Derived, also address of arr[1].x
+8 = 
0x7fffffffe320  // 3rd Derived, also address of arr[2].x

但在 Derived::init( Base* b) 中:

b[0].x = 0x7fffffffe310  // set arr[0].x to 0
+4 =
b[1].x = 0x7fffffffe314  // set arr[0].y to 0
+4 =
b[2].x = 0x7fffffffe318  // set arr[1].x to 0

因此,您已将 arr[0].x 设置为 0,将 arr[1].x 设置为 0,顺便将 arr[0].y 设置为 0。这不是您想要的。解决方案是将 Derived::init 更改为

void Derived::init( Derived *d) {
  for( int i = 0; i < 3; ++i) {
    d[i].x = 0;
  }
}

或者更好,遵循更通用的编程原则:

template < size_t N>
void Derived::init( Derived (&d)[N] ) {
    for( int i = 0; i < N; ++i) {
        d[i].x = 0;
    }
}

关于c++ - 派生类的一些问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22306851/

相关文章:

getter 的 c++ const 正确性问题

java - 公共(public)接口(interface) ITMark<E extends Comparable<E>>

java到C/C++(carbide c/c++)转换

char 和 int 之间的 C++ 转换结果错误

c++ - 如何在 C++ 中获取指向 char[] 的指针的内存地址

javascript - 下划线/lodash合并数组

iphone - 将选择器上的分数格式化为最小公分母?

ruby - 这仍然是一个类变量吗?

c++ - 请解释这个执行强制转换和类型检查的硬核宏

arrays - 将参数从 1 个函数传递给另一个函数进行循环?