class A {
public:
virtual void f() = 0;
};
class B : public A {
public:
void f() final override { };
};
int main() {
B* b = new B();
b->f();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,编译器是否仍需要执行v表查找b->f();,或者是否可以B::f()直接调用,因为它已被标记final?
在定义为基础对象的向量/数组中放置新的派生对象是否合法
#include <iostream>
#include <memory>
#include <vector>
struct A
{
virtual ~A()
{
std::cout << "~A()" << std::endl;
}
};
struct B : public A
{
virtual ~B()
{
std::cout << "~B()" << std::endl;
}
};
int main()
{
std::vector<A> a(1);
a[0].~A();
:: new(std::addressof(a[0])) B();
}
Run Code Online (Sandbox Code Playgroud)
这是合法的 C++ 吗?
这个问题与这里的问题有关。讨论的要点是我们能够在编译时确定向量/数组中对象的类型,因此我们不必进行任何动态分派。我们可以使用这些信息来优化 gcc 现在正在做的事情。
我在这里向 gcc 提出了一个问题,反对这种优化的论点是,我们可能会放置新的内容来更改存储在向量/数组中的类型,但我们不确定它是否合法,因此出现了这个 stackoverflow 问题。
有趣的是,对于数组,gcc 的行为与 clang 不同,并且 gcc 本身根据数组的长度有不同的行为。当 len >= 3 时,它执行虚拟 dtor,但当 len < 3 时,它执行合格的 dtor 调用。
https://godbolt.org/z/f33Gh5EGM
编辑:
问题纯粹是“这是合法的 C++ …