C的多重继承是如何实现的?
单继承很容易实现。 例如,在 C 中,继承可以模拟为:
struct Base { int a; }
struct Descendant { Base parent; int b; }
但对于多重继承,编译器必须在新构造的类中安排多个父类。 它是如何完成的?
我看到出现的问题是:父母应该被安排在AB还是BA,或者甚至其他方式? 然后,如果我进行强制转换:
SecondBase * base = (SecondBase *) &object_with_base1_and_base2_parents;
编译器必须考虑是否更改原始指针。 虚拟也需要类似的棘手事情。
Single inheritance is easy to implement. For example, in C, the inheritance can be simulated as:
struct Base { int a; }
struct Descendant { Base parent; int b; }
But with multiple inheritance, the compiler has to arrange multiple parents inside newly constructed class. How is it done?
The problem I see arising is: should the parents be arranged in AB or BA, or maybe even other way? And then, if I do a cast:
SecondBase * base = (SecondBase *) &object_with_base1_and_base2_parents;
The compiler must consider whether to alter or not the original pointer. Similar tricky things are required with virtuals.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
C++ 创建者的以下论文描述了多重继承的可能实现:
C++ 的多重继承 - Bjarne Stroustrup
The following paper from the creator of C++ describes a possible implementation of multiple inheritance:
Multiple Inheritance for C++ - Bjarne Stroustrup
这篇相当老的 MSDN 文章介绍了如何在 VC++ 中实现它。
There was this pretty old MSDN article on how it was implemented in VC++.
对于非虚拟继承,这没有您想象的那么棘手 - 在编译强制转换时,编译器知道派生类的确切布局(毕竟,编译器进行了布局)。 通常发生的只是从派生类指针中添加/减去一个固定偏移量(对于基类之一可能为零)。
对于虚拟继承,它可能会更复杂一些 - 它可能涉及从 vtbl (或类似的)获取偏移量。
Stan Lippman 的书 “C++ 对象模型内部” 对这些东西可能(并且通常实际上)如何工作。
With non-virutal inheritance this is less tricky than you might think - at the point where the cast is compiled, the compiler knows the exact layout of the derived class (after all, the compiler did the layout). Usually all that happens is a fixed offset (which may be zero for one of the base classes) is added/subtracted from the derived class pointer.
With virutal inheritance it is maybe a bit more complex - it may involve grabbing an offset from a vtbl (or similar).
Stan Lippman's book, "Inside the C++ Object Model" has very good descriptions of how this stuff might (and often actually does) work.
父级按指定的顺序排列:
第二种情况以特定于编译器的方式处理。 一种常见的方法是使用大于平台指针大小的指针来存储额外的数据。
Parents are arranged in the order that they're specified:
Your second case is handled in a compiler-specific manner. One common method is using pointers that are larger than the platform's pointer size, to store extra data.
这是一个有趣的问题,实际上并不是 C++ 特有的。 当您使用具有多重分派和多重继承的语言(例如 CLOS)时,事情也会变得更加复杂。
人们已经注意到有不同的方法来解决这个问题。 您可能会发现在这种情况下阅读一些有关元对象协议 (MOP) 的内容很有趣......
This is an interesting issue that really isn't C++ specific. Things get more complex also when you have a language with multiple dispatch as well as multiple inheritance (e.g. CLOS).
People have already noted that there are different ways to approach the problem. You might find reading a bit about Meta-Object Protocols (MOPs) interesting in this context...
它完全取决于编译器如何完成,但我相信它通常通过 vtable 的层次结构完成。
Its entirely down to the compiler how it is done, but I beleive its generally done througha heirarchical structure of vtables.
我进行了简单的实验:
输出是:
很高兴认识到静态转换并不总是意味着“更改类型而不触及内容”。 (好吧,当数据类型彼此不适合时,也会对内容产生干扰,但在我看来这是不同的情况)。
I have performed simple experiment:
Output is:
It's good to realise that static casting does not always mean "change the type without touching the content". (Well, when data types do not fit each other, then there will be also an interference into content, but it's different situation IMO).