这会限制类仅在当前帧中具有生存期吗?
Would this restrict the class to be have a lifetime in the current frame only?
本文关键字:生存期 更新时间:2023-10-16
我想将特定类限制为仅在堆栈上创建(而不是通过分配)。这样做的原因是,在堆栈上,生命周期最后开始的对象将是第一个被销毁的对象,我可以创建一个层次结构。我是这样做的:
#include <cstddef>
#include <iostream>
class Foo {
public:
static Foo createOnStack() {
return {};
}
~Foo () {
std::cout << "Destructed " << --i << std::endl;
}
protected:
static int i;
Foo () {
std::cout << "Created " << i++ << std::endl;
}
Foo (const Foo &) = delete;
};
int Foo::i = 0;
构造函数通常应该推送层次结构堆栈,析构函数会弹出它。我在这里替换了它以证明概念。现在,使用此类对象的唯一方法是将其存储在临时引用中,如下所示:
int main() {
Foo && a = Foo::createOnStack();
const Foo& b = Foo::createOnStack();
return 0;
}
我现在的问题是,这在C++标准下有多安全?是否还有一种方法可以在堆上合法地创建一个Foo
或将其从您的函数传递到另一个帧(也就是从您的函数返回它),而不会遇到未定义的行为?
编辑:链接到示例 https://ideone.com/M0I1NI
撇开protected
后门不谈,C++17 copy elision 以两种方式打破了这一点:
#include<iostream>
#include<memory>
struct S {
static S make() {return {};}
S(const S&)=delete;
~S() {std::cout << '-' << this << std::endl;}
private:
S() {std::cout << '+' << this << std::endl;}
};
S reorder() {
S &&local=S::make();
return S::make();
}
int main() {
auto p=new S(S::make()),q=new S(S::make()); // #1
delete p; delete q;
reorder(); // #2
}
new
的使用是显而易见的,并且已经进行了讨论。- C++17 还允许 prvalue 通过堆栈帧传播,这意味着可以在返回值之前创建
local
,并在该返回值处于活动状态时销毁。
请注意,在 local
属于类型 S
但返回值是其他(可移动)类型的情况下,第二种情况已经存在(正式在 C++14 中,很久以前非正式地存在)。 一般来说,您不能假设即使是自动对象生存期也能正确嵌套。
相关文章:
- GCC对可能有效的代码抛出init list生存期警告
- 在不复制临时对象的情况下延长其生存期
- 结束另一个线程中使用的对象的生存期
- "this"指针的值在对象的生存期内是否恒定?
- 创建具有全局生存期的 UObject
- C++17 和静态临时生存期的参考扩展
- 数组对象的生存期是否在重用其元素存储时结束?
- 共享指针生存期
- 具有空洞初始化的对象的生存期
- 如何在向量列表初始化时避免对象复制以及如何延长临时的生存期
- 指针引用的生存期(以 C++为单位)
- 子表达式中临时对象的生存期
- 对临时对象的Const引用不会延长其生存期
- 对象存在与对象生存期不同吗
- 指向对象生存期之外的已分配内存的指针是"invalid pointer[s]"还是"pointer[s] to an object"?
- 全局静态生存期?他们会让你的程序崩溃吗?
- "std::function"的简单版本:函数对象的生存期?
- 您能否根据是否使用返回值来保证不同的生存期行为?
- 理解C++指针生存期/僵尸指针
- 有什么方法可以延长C++中临时对象的生存期吗