派生类的一些问题
Some trouble with derived classes
我试图实现下面的函数和类,但输出为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
移动,这导致数组中第一个和第二个Derived
以及第一个Derived
的y
的x
成员初始化,但不是Derived
的x
。
指针的算术运算是基于对象类型的大小完成的指针
考虑以下内存布局(在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;
}
}
原因是init()不知道您实际上传递的是Derived*而不是Base*。
在init()函数的循环中,假设要到达数组中的下一项,sizeof(Base)被添加到指针中,而不是sizeof(Derived)
change
cout<<"b["<<i<<"] "<<arr[i].x;
cout<<"b["<<i<<"] "<<arr[i].x<<endl;
然后你会看到正确的数字。
endl的额外功能是刷新与该流相关的缓冲区。如果不这样做,它有时会输出一些随机数。
首先,你通过值传递指针(*b)给函数init(),而不是通过引用。
这里有一个很好的解释为什么这很重要,他们解释得比我更好
试着让init函数看起来像这样
init(Base& *b)
相关文章:
- 从基指针到派生的强制转换问题
- 关于C++从派生类调用在基类中实现的虚拟函数的问题
- SIGSEGV 因为基/派生类的继承问题
- C 两个派生的类中有彼此的对象(包括问题)
- 使用 boost::序列化将派生类指针序列化为向量时出现问题
- 类型特征检查 CRTP 派生,在基类中,问题是未定义的类型
- 有关通过派生类在命名空间内继承的问题
- 如果私有虚拟函数被覆盖为派生类中的公共函数,那么问题是什么
- 分配派生类的对象时出现问题,其中基类具有抽象虚函数
- 覆盖派生类的函数时遇到问题
- 派生类中的模板存在问题
- 使用基对象修改/访问派生类的信息的有问题的设计
- 设计问题迫使我将基类向下转换为派生类型
- 从嵌套在模板中的类派生时编译问题
- 从派生类调用基类函数时出现问题
- 派生类问题中的C++继承默认构造函数
- 如何解决具有多个派生类的抽象基类的继承问题
- 使用Boost:serialize反序列化指向派生类的指针时出现问题
- c++派生类构造函数问题
- 继承的问题:派生类不继承基类