Pao*_*oni 7 c++ constructor c++11
对于内置类型,如int,您可以简单地写入任何内容来延迟初始化.有没有办法对C++对象做同样的事情?
我写了这个代码来完成这项工作,但我想知道是否有一种惯用的方法.如果是这样,它是什么?甚至在引入对齐存储之前是否可能?
#include <utility>
#include <type_traits>
template <typename T>
struct delayed {
delayed() { unset_init(); }
template <typename...Args> void init(Args&&... args) {
new ( memory() ) T(std::forward<Args>(args)...);
set_init();
}
operator T*() {
return memory();
}
~delayed() {
if (get_init()) {
memory()->~T();
unset_init();
}
}
private:
T* memory() { return reinterpret_cast<T*>(&bytes_); }
unsigned char* raw_memory() { return reinterpret_cast<unsigned char*>(&bytes_); }
unsigned char& init() { return *( raw_memory() + sizeof(T) ); }
bool get_init() { return init() != 0; }
void set_init() { init() = 1; }
void unset_init() { init() = 0; }
typename std::aligned_storage<sizeof(T) + 1, alignof(T)>::type bytes_{};
};
Run Code Online (Sandbox Code Playgroud)
Bri*_*ian 17
在C++ 17及更高版本中,我希望首选的习语是std::optional<T>
.在C++ 11和C++ 14中,std::unique_ptr<T>
虽然它具有需要堆分配的明显缺点,但它似乎很常见.
用法:
std::optional<T> t; // initially empty
// do some stuff
// now we're ready to create the T value
t.emplace(foo, bar); // constructs the T with foo, bar as args
Run Code Online (Sandbox Code Playgroud)
首先,int
变量是一个 C++ 对象。想必当您谈论 C++ 对象而不是 时int
,您指的是类类型对象。但不仅仅是类类型对象,因为你可以这样做:
struct Blah{ int x; int y; };\n\nauto main() -> int\n{\n Blah o; // Uninitialized, indeterminate value.\n // Whatever\n o = {6, 7};\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n因此,您可能指的是至少具有一个用户定义的构造函数的类类型的对象。
\n\n相对于用于访问它的对象的声明,延迟此类对象的初始化的最常见方法包括
\n\nstd::vector
作为一个扩展数组,…重构本质上是将以后使用的代码移动到一个或多个函数中。
\n\n例如,丑陋且低效的延迟初始化代码
\n\nunique_ptr<MyClass> p;\n\nif( condition() )\n{\n // Some code here, then\n p.reset( new MyDerivedA( 123 ) );\n}\nelse\n{\n // Some code here, then\n p.reset( new MyDerivedB( "andromeda" ) );\n}\n// Code using *p here.\n
Run Code Online (Sandbox Code Playgroud)\n\n…可能会被重构为
\n\nvoid foo( MyClass&& o )\n{\n // Code using o here.\n}\n\n\xe2\x80\xa6\nif( condition() )\n{\n // Some code here, then\n foo( MyDerivedA( 123 ) );\n}\nelse\n{\n // Some code here, then\n foo( MyDerivedB( "andromeda" ) );\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n不太常见的方式包括
\n\n放置new
在一些适当对齐的字节数组中,就像在您的代码中一样,并且
如果您的类是可移动的,请使用Optional_
类(Barton-Nackman Fallible
、Boost 和 C++17optional
)。
我认为,这些技术是否可以被视为延迟初始化的惯用方法,是相当主观的个人意见。
\n 归档时间: |
|
查看次数: |
1268 次 |
最近记录: |