奇怪的多继承问题 [英] strange multi-inheritance problem
问题描述
首先,我知道下面的代码很糟糕,但它来自一个库我已经使用
了,我无法改变它。
A级{
//一些原始成员
};
B级{
//一些原始成员
};
C级:公共A,B {
//没有会员
};
main(){
//我知道sizeof(A )= 16,sizeof(B)= 60
C * pc =(C *)新字符[sizeof(A)+ sizeof(B)];
B * pb =(B *)pc;
char * p1 =(char *)pc;
char * p2 =(char *)pb;
cout<< offset: << (p2-p1)<<结束;
}
让我感到惊讶的是,偏移是20而不是16。你知道
可能的原因?
问候。
First, I know the following code is bad, but it''s from a library I have
to use, and I can''t change it.
class A {
// some primitive members
};
class B {
// some primitive members
};
class C : public A, B {
// no members
};
main() {
// I know sizeof(A) = 16, sizeof(B) = 60
C * pc = (C*) new char[sizeof(A) + sizeof(B)];
B * pb = (B*) pc;
char * p1 = (char *) pc;
char * p2 = (char *) pb;
cout << "offset : " << (p2 - p1) << endl;
}
What surprised me is that the offset is 20 instead of 16. Do you know
the possible reason?
Regards.
推荐答案
事实证明sizeof(C)= 80.
Also it turns out that sizeof(C) = 80.
" Patricia" < LA ****** @ gmail.com>在消息中写道
news:11 ********************** @ o13g2000cwo.googlegr oups.com ...
"Patricia" <la******@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
首先,我知道下面的代码很糟糕,但它来自我使用的库,我无法改变它。
A类{
//一些原始成员
};
B类{
//一些原始成员
};
C班:公众A,B {
//没有会员
};
main(){
main的返回类型必须明确指定为int:
int main(){
//我知道sizeof(A)= 16,sizeof( B)= 60
你还知道sizeof(C)吗?
C * pc =(C *)new char [sizeof(A)+ sizeof (B)];
这是未定义的行为。你不能假设sizeof(C)与sizeof(A)和sizeof(B)相等。
。你也不能假设那里有一个C对象
。那些只是一堆未初始化的角色。你不能假设他们可以很容易地用作C.
B * pb =(B *)pc;
实际上,C私下继承自B。你不能假设上面演绎的C风格
会让你访问B部分C.如果你打算从B公开继承
,那么不需要演员:
B * pb = pc;
char * p1 =(char *)pc;
char * p2 = (char *)pb;
cout<< offset: << (p2-p1)<< endl;
}
让我感到惊讶的是,偏移是20而不是16。你知道可能的原因吗?
First, I know the following code is bad, but it''s from a library I have
to use, and I can''t change it.
class A {
// some primitive members
};
class B {
// some primitive members
};
class C : public A, B {
// no members
};
main() {
The return type of main must be explicitly specified as int:
int main() {
// I know sizeof(A) = 16, sizeof(B) = 60
Do you also know sizeof(C)?
C * pc = (C*) new char[sizeof(A) + sizeof(B)];
That is undefined behavior. You cannot assume that sizeof(C) will be equal
to sizeof(A) and sizeof(B). Nor can you assume that there is a C object
there. Those are just a bunch of uninitialized characters. You cannot assume
that they can be readily used as a C.
B * pb = (B*) pc;
Actually, C inherits from B privately. You can''t assume that the C-style
cast above will give you access to the B part a C. If you intended to
inherit publicly from C, then the cast is not needed:
B * pb = pc;
char * p1 = (char *) pc;
char * p2 = (char *) pb;
cout << "offset : " << (p2 - p1) << endl;
}
What surprised me is that the offset is 20 instead of 16. Do you know
the possible reason?
>
原因是程序的行为未定义。
作为旁注,你应该放弃使用C风格的演员表。使用C ++的一个
转换运算符来明确你所说的内容,并在转换非法时从编译器获得帮助
。 br />
Ali
The reason is that the program''s behavior is undefined.
As a side note, you should abandon using the C-style casts. Use one of C++''s
casting operators to make it explicit what you''re saying, and to get help
from the compiler when the casting is illegal.
Ali
" Patricia" < LA ****** @ gmail.com>在消息中写道
news:11 ********************** @ o13g2000cwo.googlegr oups.com ...
"Patricia" <la******@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
首先,我知道下面的代码很糟糕,但它来自我使用的库,我无法改变它。
A类{
//一些原始成员
};
B类{
//一些原始成员
};
C班:公众A,B {
//没有会员
};
main(){
//我知道sizeof(A) = 16,sizeof(B)= 60
C * pc =(C *)new char [sizeof(A)+ sizeof(B)];
B * pb =(B *)pc;
char * p1 =(char *)pc;
char * p2 =(char *)pb;
cout<< offset: << (p2-p1)<< endl;
}
让我感到惊讶的是,偏移是20而不是16。你知道可能的原因吗?
First, I know the following code is bad, but it''s from a library I have
to use, and I can''t change it.
class A {
// some primitive members
};
class B {
// some primitive members
};
class C : public A, B {
// no members
};
main() {
// I know sizeof(A) = 16, sizeof(B) = 60
C * pc = (C*) new char[sizeof(A) + sizeof(B)];
B * pb = (B*) pc;
char * p1 = (char *) pc;
char * p2 = (char *) pb;
cout << "offset : " << (p2 - p1) << endl;
}
What surprised me is that the offset is 20 instead of 16. Do you know
the possible reason?
>
以下是做你想做的事情的更好方法:
#include< iostream>
#include<记忆>
A级{
//一些原始成员
int a [4];
};
B级{
//一些原始成员
int a [15];
};
C级:公众A,公共B {
//没有会员
};
int main(){
std :: cout<< " sizeof(A): << sizeof(A)
<< " sizeof(B): << sizeof(B)
<< " sizeof(C): << sizeof(C)
<< ''\ n'';
//分配一个缓冲区
char * buffer = new char [sizeof(C)];
//使用placement new在该缓冲区上构造一个对象
C * pc = new(reinterpret_cast< void *>(缓冲区))C();
//有效的上传
B * pb = pc;
char * p1 = reinterpret_cast< char *>(pc);
char * p2 = reinterpret_cast< char *>(pb);
//警告:下面有未定义的行为!我们不能减去两个
//指针,除非它们指向同一个
//数组的对象。然而,结果可能对给定系统有用。
std :: cout<< offset: << (p2-p1)<< endl;
//手动销毁C对象并释放缓冲区
pc-> ~C();
删除缓冲区;
}
阿里
The following is a better way of doing what you are trying to do:
#include <iostream>
#include <memory>
class A {
// some primitive members
int a[4];
};
class B {
// some primitive members
int a[15];
};
class C : public A, public B {
// no members
};
int main() {
std::cout << " sizeof(A): " << sizeof(A)
<< " sizeof(B): " << sizeof(B)
<< " sizeof(C): " << sizeof(C)
<< ''\n'';
// Allocate a buffer
char * buffer = new char[sizeof(C)];
// Use placement new to construct an object on that buffer
C * pc = new (reinterpret_cast<void *>(buffer)) C();
// A valid up-cast
B * pb = pc;
char * p1 = reinterpret_cast<char *>(pc);
char * p2 = reinterpret_cast<char *>(pb);
// WARNING: Undefined behavior below! We cannot subtract two
// pointers unless they point to objects of the same
// array. Nevertheless, the results may be useful on a given system.
std::cout << "offset : " << (p2 - p1) << endl;
// Destroy the C object manually and release the buffer
pc->~C();
delete buffer;
}
Ali
这篇关于奇怪的多继承问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!