繁体   English   中英

RTTI和c ++中的虚函数。 gcc的实现方法是否必要?

[英]RTTI and virtual functions in c++ . Is the implementation approach of gcc necessary?

在尝试了解虚函数和RTTI的内部工作原理时,我通过检查gcc编译器观察了随后的事实:

当结构或类具有虚函数时,通过使用确定其类型的指针来扩展结构或类所占用的空间。

而且,当多重继承处于活动状态时,每个子结构都会添加另一个指针。 因此,例如一个结构:

struct C: public A, public B{...}

用A和B的数据加上两个指针创建一个结构。 那是内存和效率消耗。 问题是是否需要这样做。

我没有使用这些参数的经验,但是我想询问是否存在错误的逻辑思想如下:

a)当我们声明某个结构类型的变量时,我们知道它的类型。 因此,当我们必须按值将该变量传递给另一个函数时,我们知道它的类型,并且可以将其作为普通的旧结构以及一个额外的值(表示该类型)传递给我(我是指编译器应该注意这一点)。

b)当我们通过引用或指针传递结构时,我们再次知道起始类型,并且我们可能会传递一个指针以及一个额外的值来指示类型。

为了将按值传递的结构分配给较窄的类型,我们只需要采取必要的子部分(偏移量计算)。 为了更改为较窄的指针,我们必须调整指针并相应地更改指示类型的额外值。

因此,按照那条原则,仅当在堆栈上的函数之间传递调用的参数时,才需要有额外的类型指示,并且不需要将它们保存在每个结构中。

我想念什么? 我看到的唯一需要将类型信息与数据一起存储的情况是,当我们使用Union时,我们需要保存某种类型的特定结构列表,但是任何情况下都可以通过其他方式解决。 因此,问题在于,除了在函数之间传递参数时,是否还需要动态类型信息,以及该标准最终要求的是否以及在何处。

我想念什么?

rtti和dynamic_cast必须能够从其任何接口推断出对象的布局。

除非每个接口都封装了指向该信息的指针,否则您将如何做?

RTTI的示例:

struct A { virtual ~A() = default; };  // virtual base class

struct B : A {}; // derived polymorphic class

A* p = new B();
std::cout << typeid(*p).name() << std::endl;

读者练习:

  1. 哪个班的名字被打印出来?

  2. 为什么?

我认为,以下代码将对所有内容进行解释:

// in header.h
struct Base {
   virtual void foo() = 0;
};

// in impl.cpp
void work(Base* b) {
    b->foo();
}

假设上面的代码被编译到C ++库中。 此后再也没有碰过。

现在,一段时间后,我们编写以下代码:

#include <header.h>
struct D : Base {
    void foo() { std::cout << "Foo!\n"; }
};

void my() {
    D* d = new D;
    work(d);
}

如您所见,我们不可能将任何类型传递给work() -编译时, D甚至不存在! 通过指向虚拟函数表的指针来实现虚拟函数的优雅-这就是那些指针-允许上述设计。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM