奇怪的多继承问题 [英] strange multi-inheritance problem

查看:52
本文介绍了奇怪的多继承问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



首先,我知道下面的代码很糟糕,但它来自一个库我已经使用

了,我无法改变它。


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆