是否可以使用静态创建的类实例,但是有参数?这就是我的想法:
/* main.cpp */
int main(int argc, char ** argv){
/* obtain parameters from command line and pass one of them to CLog*/
}
/* CLog.h */
class CLog{
operator <<();
/* some other stuff */
};
extern CLog log;
简而言之,我希望我的项目中的所有类都可以访问这个类,因此extern
,我希望它被创建为非指针(以使用log<<"something"
启用输出),但我想在创建它之前传递一个参数。那可能吗?或者是否有解决方法,以便我不必将其称为(*log)<<"something"
?
答案 0 :(得分:2)
log
的创建在调用main
之前,因此您无法传递需要在main
之后准备的参数。您可以通过以下方式传递参数:
class CLog{
void setParameters(...);
...
/* some other stuff */
};
extern CLog log;
...
int main(int argc, char ** argv){
log.setParameters(...);
}
答案 1 :(得分:2)
您不能直接执行此操作,因为在main
开始运行之前初始化全局变量。但是,您可以使用placement new
:
#include <new>
char CLogBuf[sizeof(CLog)];
CLog* pLog = nullptr;
int main(int argc, char** argv)
{
pLog = new (CLogBuf) CLog(params);
return 0;
}
是否值得,是你的决定。更直接的解决方案是@ M.M建议的解决方案。
在评论中讨论之后,这里是一个带引用而不是指针的版本,允许保留原始界面:
#include <new>
char CLogBuf[sizeof(CLog)];
const CLog& log = *((CLog*)CLogBuf);
int main(int argc, char** argv)
{
(void) (new (CLogBuf) CLog(params));
return 0;
}
这种方法的主要优点是将接口减少到所需的最小值:没有什么能阻止不同方多次调用初始化方法,最有可能破坏程序语义。这种方法完全消除了init方法,从而消除了这个问题。
答案 2 :(得分:0)
我在这种情况下的偏好是在整个代码中使用一个访问器,它通过引用返回单例,以方便调用。访问器的实现可以简单地取消引用现有的全局,或者可以使用给定的参数懒得创建它,如下所示:
// In public header:
extern CLog & Log();
// In private cpp:
extern CLog & Log();
{
static CLog * pLog = nullptr;
if( !pLog )
pLog = new pLog(/* params, which could be fetched from command line outside of main */);
return *pLog;
}
// In client code:
Log().DoSomething();
如果您不喜欢parens,并且真的想要对象引用的外观和感觉,您可以创建一个包装器对象并通过operator-&gt;访问延迟创建的CLog,就像智能指针一样。< / p>