-1

是否可以有一个静态创建的类实例,但有一个参数?这就是我的想法:

/* 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"

4

3 回答 3

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;
}

值不值是你的决定。更直接的解决方案是@MM 建议的解决方案

在评论中的讨论之后,这是一个带有引用而不是指针的版本,允许保留原始界面:

#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 方法,从而消除了问题。

于 2013-04-26T11:02:20.737 回答
2

的创建log是在调用之前,main因此您不能传递需要在之后准备的参数main。您可以通过这种方式传递参数:

class CLog{
    void setParameters(...);
     ...
    /* some other stuff */
};

extern CLog log;

...

int main(int argc, char ** argv){
    log.setParameters(...);
}
于 2013-04-26T10:54:24.390 回答
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();

如果您不喜欢括号,并且真的想要对象引用的外观和感觉,您可以创建一个包装对象并通过 operator-> 访问延迟创建的 CLog,就像智能​​指针一样。

于 2013-04-26T13:49:24.503 回答