延期构件施工
Deferred member construction
我有以下结构:
struct Logger::LoggerImpl {
std::wofstream loggerStream;
}
当我创建LoggerImpl时,显然会隐式创建std::wofstream(通过编译器的默认构造函数)。
我的问题是,有没有一种方法可以在不使用指针的情况下阻止(或推迟)wofstream的构建?因为我稍后会用给定的文件名创建它。
我知道在这种情况下,这没有什么不同,但我是在理论基础上问的。
为什么不使用默认构造函数创建std::wofstream
,然后只创建open()
文件?绑定包含对象的生命周期似乎是正确的方法。
在C++11中,您还可以将带有构造函数的对象放入union
中。当然,结果是,您需要接管union
成员的终身管理。但是,通过这种方式,可以将特定成员的构造推迟到以后。请注意,在下面的代码中使用new
实际上只是放置新,将对象构建到合适的位置。这里有一个例子:
#include <iostream>
#include <fstream>
#include <new>
class foo
{
bool constructed;
union helper {
helper() {}
~helper() {}
std::ifstream stream;
} member;
public:
foo(): constructed() {}
~foo() {
if (constructed) {
using std::ifstream;
this->member.stream.~ifstream();
}
}
void open(std::string const& name) {
new (&this->member.stream) std::ifstream(name);
constructed = true;
}
std::streambuf* rdbuf() {
return this->member.stream.rdbuf();
}
};
int main()
{
foo f;
f.open("foo.cpp");
std::cout << f.rdbuf();
}
如果将"不使用指针"的定义扩展为"不必直接使用std::wofstream *
",则可以:
struct Logger::LoggerImpl {
std::shared_ptr<std::wofstream> loggerStream;
void init () {
loggerStream = std::make_shared<std::wofstream> ();
}
};
我说拉伸是因为你没有直接处理std::wofstream *
。这是我能想出的最好的办法。
在各种情况下推迟成员的构建非常有意义。这里有几种方法可以做到这一点;实现之间的差异是由于延迟的目的不同。
首次使用时初始化;原因:在需要之前不要浪费资源。
class Logger::LoggerImpl
{
private:
std::wofstream * loggerStream; // Don't expose to other classes
std::wofstream * GetLoggerStreamImpl()
{
if( loggerStream == NULL )
{
loggerStream = new std::wofstream;
}
return loggerStream;
}
public:
LoggerImpl() : loggerStream(NULL)
{
}
std::wofstream * GetLoggerStream()
{
return GetLoggerStreamImpl();
}
void DoSomethingWithLoggerStream()
{
GetLoggerStreamImpl();
// Do whatever you need with loggerStream
}
};
通过专用方法进行初始化;原因:用于初始化的参数以前未知。
class Logger::LoggerImpl
{
private:
std::wofstream * loggerStream; // Don't expose to other classes
std::wofstream * OpenLoggerStreamImpl( string filename )
{
if( loggerStream == NULL )
{
loggerStream = new std::wofstream( filename );
}
return loggerStream;
}
public:
LoggerImpl() : loggerStream(NULL)
{
}
std::wofstream * OpenLoggerStream( string filename )
{
return OpenLoggerStreamImpl( filename );
}
void DoSomethingWithLoggerStream()
{
if( loggerStream == NULL )
{
throw Exception( "Aye, Caramba! Logging stream wasn't open yet!" );
}
// Do whatever you need with loggerStream
}
};
相关文章:
- 为什么 boost::interprocess::managed_shared_memory 在施工时会抛出 boost
- 施工期间的虚函数调用
- 施工后立即在向量上调用清晰?
- 安置回去在原地施工失败
- 施工中的自我参考
- call call cons构件功能的std ::元素的每个元素
- 带有柔性阵列构件的包装结构的便携式替代方案
- 如何在C 中访问无范围分辨率运算符的标头构件类型
- 高效的施工委托
- QStyledItemDelegate 绘图自定义构件失败
- 如何使用非平凡的构造器构造静态螺纹构件
- C GRPC ::完整的施工速度约为14K
- 减少将临时对象分配给现场施工
- C 在施工中定义的容器
- 过度施工
- 对齐构件的对齐结构为成员(C )
- 格式化构造构件成员初始化,不稳定
- 您如何使用成员正确初始化构造的结构,该构件是指向const值的const指针
- 构件和模板参数语法上的指针
- 延期构件施工