构造期间的虚拟方法绕过虚拟调度C ++

问题描述 投票:0回答:1

当我编译时,clang给出以下输出:

插入虚拟方法在构造期间绕过绕过虚拟派遣

消息是什么意思?是警告我,静态调度是进行而不是虚拟调度的,还是对UB的警告?

注意,如果在混凝土的构造函数中io note
    Concrete::doSomething()
  • ,消息就会消失。
  • 这是这个ub?

say我们做

Concrete c;
。这就是我认为发生的事情:

  • 对象的记忆
  • c
分配。

抽象类的构造函数被称为。

__vptr
指向纯虚拟函数。

称为构造函数。任何非静态成员的初始化。初始化完成了,
    Concrete
  1. 现在指出了
    __vptr
    的实现。构造函数的主体是运行的,它将称为“被覆盖”。
  2. 除了我描述的事情发生的事情吗?
  3. 
    
  4. eDit
    
    
    它是clang-tidy,发出消息LLVM版本17.0.6
    	
    从构造函数或破坏者中调用虚拟函数并没有任何固有的错误,并且这样做是
    not绕过虚拟调度。说那些过分简化的人。 Concrete
    真正的规则仅仅是根据构造函数(和破坏者)中的虚拟函数调用,该函数是根据当前正在运行的类的类别的规则来派遣的。
    
  5. doSomething()

当还有另一个构造水平时,人们往往会感到困惑:


doSomething()

这里的关键是,在构建struct base { virtual void f() { } void g() { f(); } base() { f(); // always calls base::f g(); // always calls base::f } }; struct intermediate : base { void f(); intermediate() { f(); // always calls intermediate::f g(); // always calls intermediate::f via virtual dispatch } };

子对象期间,所有虚拟呼叫都像在类型

intermediate i; // base::base calls to f() and g() both call base::f // intermediate::intermediate calls to f() and g() both call intermediate::f i.g(); // calls intermediate::f

对象上一样,即使要构造的实际对象的类型为
c++ clang virtual-functions
1个回答
1
投票
。 construct

的构造函数中没有intermediate

没有呼叫
intermediate
“绕过”虚拟调度。虚拟函数调用转到针对其构造函数正在运行的类定义的版本。将其描述为“绕过”虚拟调度的人们开始懒惰。声称从构造函数和破坏者中调用虚拟功能的人本质上是危险的人。是的,您必须了解发生了什么。不,这里没有恶魔潜伏。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.