gpt4 book ai didi

c++ - 如何保持在堆栈上分配的对象的动态类型?

转载 作者:行者123 更新时间:2023-11-30 01:51:55 34 4
gpt4 key购买 nike

假设我有:

class A { };
class B : public A { };
A f() {
if (Sunday())
return A;
else
return B;
}

显然,自 A 以来,这不起作用的复制构造函数将被调用。有没有办法在不丢失其类型的情况下返回堆栈分配的对象?

我试过使用 std::shared_ptr<A>但它让我陷入了另一个问题 std::shared_ptr<B>不是 std::shared_ptr<A> .

最佳答案

不可能立即从创建对象的函数中返回堆栈分配的(即本地)对象。局部对象在函数返回时被销毁。您可以使用各种“智能指针”和类似技术隐藏/混淆对象分配的实际性质,但对象本身应该动态分配。

除此之外,只要遵守本地对象生命周期规则,本地对象的多态性与其他任何对象的工作方式完全相同。只需使用指针或引用

A a;
B b;

A *p = Sunday() ? &a : &b;
// Here `*p` is a polymorphic object
只要本地对象存在,上例中的

指针 p 就保持有效,这意味着您不能从函数返回 p

此外,正如您在上面的示例中看到的,它无条件地预先创建两个 对象,然后选择两者之一,同时不使用第二个。这不是很优雅。您不能在 if 语句的不同分支中创建此类对象的不同版本,原因与您不能以多态方式从函数返回本地对象的原因相同:一旦创建对象的本地 block 完成,对象被销毁。

后一个问题可以通过使用原始缓冲区和手动就地构造来解决

alignas(A) alignas(B) char object_buffer[1024]; 
// Assume it's big enough for A and B

A *p = Sunday() ? new(buffer) A() : new (buffer) B();
// Here `*p` is a polymorphic object
p->~A(); // Virtual destructor is required here

但它看起来并不漂亮。一种类似的技术(涉及缓冲区的复制)可能用于使本地多态对象在 block 边界中幸存下来(请参阅@Dietmar Kühl 的回答)。

因此,再次强调,如果您只想创建两个对象中的一个对象并让您的对象在 block 边界中存活下来,那么立即解决方案将本地对象放在一边是不可能的。您将不得不使用动态分配的对象。

关于c++ - 如何保持在堆栈上分配的对象的动态类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25474742/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com