- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我在阅读 C++ 中的虚拟继承时在一个网站上发现了这个
当使用多重继承时,有时需要使用虚拟继承。一个很好的例子是标准 iostream 类层次结构:
//Note: this is a simplified description of iostream classes
class ostream: virtual public ios { /*..*/ }
class istream: virtual public ios { /*..*/ }
class iostream : public istream, public ostream { /*..*/ }
//a single ios inherited
C++ 如何确保只存在一个虚拟成员的单个实例,而不考虑从它派生的类的数量? C++ 使用额外的间接层来访问虚拟类,通常是通过指针。换句话说,iostream 层次结构中的每个对象都有一个指向 ios 对象共享实例的指针。额外的间接级别会产生轻微的性能开销,但付出的代价很小。
我对以下陈述感到困惑:
C++ 使用额外的间接级别来访问虚拟类,通常通过指针的方式
谁能解释一下?
最佳答案
要解决的基本问题是,如果将指向最派生类型的指针强制转换为指向其基类之一的指针,则该指针必须引用内存中的地址,代码可以从该地址中找到该类型的每个成员不知道派生类型。对于非虚拟继承,这通常是通过具有精确的布局来实现的,而这又是通过包含一个基类子对象然后添加派生类型的额外位来实现的:
struct base { int x; };
struct derived : base { int y };
派生的布局:
--------- <- base & derived start here
x
---------
y
---------
如果您添加第二个派生类型和一个最派生类型(同样,没有虚拟继承),您会得到如下结果:
struct derived2 : base { int z; };
struct most_derived : derived, derived 2 {};
使用这种布局:
--------- <- derived::base, derived and most_derived start here
x
---------
y
--------- <- derived2::base & derived2 start here
x
---------
z
---------
如果您有 most_derived
对象,然后绑定(bind) derived2
类型的指针/引用它将指向标有 derived2::base
的行.现在,如果从 base 继承是虚拟的,那么应该有一个 base
的实例。 .为了便于讨论,假设我们天真地删除了第二个 base
:
--------- <- derived::base, derived and most_derived start here
x
---------
y
--------- <- derived2 start here??
z
---------
现在的问题是,如果我们获得指向 derived
的指针它的布局与原始布局相同,但如果我们尝试获取指向 derived2
的指针布局会有所不同,代码在 derived2
将无法找到 x
成员。我们需要做一些更聪明的事情,这就是指针发挥作用的地方。通过添加一个指向每个虚拟继承对象的指针,我们得到了这样的布局:
--------- <- derived starts here
base::ptr --\
y | pointer to where the base object resides
--------- <-/
x
---------
同样适用于 derived2
.现在,以额外的间接为代价,我们可以找到 x
子对象通过指针。当我们可以创建 most_derived
具有单个基础的布局,它可能如下所示:
--------- <- derived starts here
base::ptr -----\
y |
--------- | <- derived2
base::ptr --\ |
z | |
--------- <--+-/ <- base
x
---------
现在输入 derived
和 derived2
现在了解如何访问基本子对象(只需取消引用 base::ptr
成员对象),同时您有一个 base
实例.如果任一中间类中的代码访问 x
他们可以这样做 this->[hidden base pointer]->x
,这将在运行时解决到正确的位置。
这里的重要一点是在 derived
编译的代码/derived2
layer 可以与该类型的对象或任何派生对象一起使用。如果我们写第二个 most_derived2
继承顺序颠倒的对象,则它们的布局为y
和 z
可以交换,以及指向 derived
的指针的偏移量或 derived2
base
的子对象子对象会有所不同,但访问 x
的代码仍然是一样的:取消引用你自己的隐藏基指针,保证如果 derived
中的方法是最终的覆盖者,并且访问 base::x
那么无论最终布局如何,它都会找到它。
关于c++ - C++中的虚拟继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5179854/
我使用的是 PHP 5.3 稳定版,有时会遇到非常不一致的行为。据我所知,在继承中,父类(super class)中的所有属性和方法(私有(private)、公共(public)和 protected
所以我一直在努力寻找正确的方法来让应该非常简单的继承发挥作用(以我想要的方式 ;)),但我失败得很惨。考虑一下: class Parent { public String name = "Pare
给定这些类: class Father { public Father getMe() { return this; } } class Child extends Father {
为什么最后打印“I'm a Child Class”。 ? public class Parent { String parentString; public Parent()
我知道有很多类似的问题对此有很多很好的答案。我试着看看经典的继承方法,或者那些闭包方法等。不知何故,我认为它们对我来说或多或少是“hack”方法,因为它并不是 javascript 设计的真正目的。
我已经使用表单继承有一段时间了,但没有对以下方法进行太多研究。只需创建一个新类而不是表单并从现有表单继承并根据需要将所需控件转换为 protected 。 Visual Studio 2010 设计器
我原以为下面的代码片段会产生编译错误,因为派生类不会有我试图在 pub_fun() 中访问的 priv_var。但是它编译了,我得到了下面提到的输出。有人可以解释这背后的理论吗? class base
继承的替代方案有哪些? 最佳答案 Effective Java:优先考虑组合而不是继承。 (这实际上也来自《四人帮》)。 他提出的情况是,如果扩展类没有明确设计为继承,继承可能会导致许多不恰当的副作用
我有2个类别:动物( parent )和狗(动物的“ child ”),当我创建一个 Animal 对象并尝试提醒该动物的名称时,我得到了 undefined ,而不是她的真名。为什么?(抱歉重复发帖
我试图做继承,但没想到this.array会像静态成员一样。我怎样才能让它成为“ protected /公开的”: function A() { this.array = []; } func
在创建在父类中使用的 lambda 时,我试图访问子类方法和字段。代码更容易解释: class Parent { List> processors; private void do
如果我有一个对象,我想从“ super 对象”“继承”方法以确保一致性。它们将是混合变量。 修订 ParentObj = function() { var self = this; t
class Base { int x=1; void show() { System.out.println(x); } } class Chi
目前我正在尝试几种不同的 Javascript 继承方法。我有以下代码: (“借用”自 http://www.kevlindev.com/tutorials/javascript/inheritanc
我在 .popin-foto 元素中打开一个 popin。当我尝试在同一元素中打开子类 popin 时,它不起作用。 代码 这是 parent function Popin(container, ti
我有以下两个类: class MyClass { friend ostream& operatorvalue +=1; return *this; } 现在
有没有办法完全忽略导入到 html 文件中的 header 中的 CSS 文件? 我希望一个页面拥有自己独立的 CSS,而不是从任何其他 CSS 源继承。 最佳答案 您可以在本地样式表中使用 !imp
Douglas Crockford似乎喜欢下面的继承方式: if (typeof Object.create !== 'function') { Object.create = functio
假设我有以下代码: interface ISomeInterface { void DoSomething(); void A(); void B(); } public
class LinkedList{ public: int data; LinkedList *next; }; class NewLinkedList: public Lin
我是一名优秀的程序员,十分优秀!