【问题标题】:C++ Singelton Class Vs Namespaces Vs Public Static VariablesC++ 单例类与命名空间与公共静态变量
【发布时间】:2012-04-12 11:15:12
【问题描述】:

以下哪种方法最适合定义全局变量:

  1. 公共静态类变量
  2. 将类的单个对象与所有私有变量一起使用:(单例类)
  3. 命名空间 - 我是否应该只使用命名空间。

我不确定这个问题是否有意义。只是试图找到最佳做法。

下面的代码在语法上不正确,但我认为它应该传达这个想法:

----------------------------------------------------------------
class Reader {
  Reader();
  Library* lib;
  static Reader* reader;
public:
  Reader* Instance () {
      if (!reader) { reader = new Reader() }
      return reader;
  }
  void setLibrary ( Library* ptr ) { lib = ptr }
  Library* getLibrary { return lib }
}

Reader* Reader::reader = NULL;

int main( ) {
  ...
  Library* lib = new Library("test");
  Reader::Instance()->setLibrary(lib);
  Reader::Instance()->getLibrary()->addCell("AND2X1");
 }

   -------------- OR -------------

class Reader {
   Reader();
public:
  static Library* lib;
}

Library* Reader::lib = NULL;

int main( ) {
  ...
  Reader::lib = new Library("test");
  Reader::lib->addCell("AND2X1");
 }

    ---------------- OR -----------------

namespace Reader {
   Library* lib = NULL;
}

int main( ) {
  ...
  Reader::lib = new Library("test");
  Reader::lib->addCell("AND2X1");
}
---------------------------------------------------------------

我正在尝试使用 Tcl_createCommand 在带有 TCL 前端的 C++ 程序中创建新命令。我无法将任何新参数传递给函数实现 因此,我需要全局变量来访问函数内的一些数据。 我为此找到的所有解决方案似乎都在使用全局变量。

我需要上述内容的另一个实例是使用 bison 生成解析器时。 使用野牛语法时,我需要定义全局变量来执行操作。

【问题讨论】:

  • nooooooooooooooooooooooooooooo 。 . .
  • 你问错了问题,关于 worst 的做法。正如 CodeChords 所说,使用 clientData
  • C++ FQA [27.15] 使用全局变量的良好编码标准是什么?以下是声明全局变量的理想方式:// int xyz; ←the thing that makes this global ideal is the leading // 如,不要使用全局变量

标签: c++ static namespaces tcl bison


【解决方案1】:

create命令的原型是:

Tcl_Command Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc)

clientData 允许您将数据与命令相关联。然后你就可以使用你需要的数据了,根本不需要全局变量!

顺便说一句,您可能想在这个问题中添加tcl 标签:-)

【讨论】:

  • 感谢 CodeChords,这真的很有帮助。
  • 我想补充的另一件事是我在使用野牛时遇到了同样的问题。除了定义全局变量之外,我可以为 Bison 文件做些什么吗?
  • ClientData 是一个void *(即一个字大小的指针),保证 Tcl 不会窥视它内部或将其转换为任何东西;它将被传递给proc 回调,根本不会对其应用任何解释。与 C++ 方法集成时,您可以通过 this 传递(可能带有额外的包装)。
【解决方案2】:

如果您想使用全局单例(您不应该这样做!但它们有时很有帮助),C++ FAQ 有一个不错的答案。

基本上:

class Foo_class {
  public:
  class bar {
    public:
    int x;
  };

  int x;
  Foo_class() { x = 2; mybar = new bar(); } // This constructor will be called on first reference to the singleton
  void set_bar(bar* what) { mybar = what; }

  bar *mybar;
};

Foo_class& Foo()
{
  static Foo_class *myclass = new Foo_class();
  return *myclass;
}

int main(void)
{
  typedef Foo_class::bar foobar;
  foobar hmph;
  hmph.x = 70;
  Foo().set_bar(hmph);
  foo().x = 7;
}

【讨论】:

  • 在以上三种方法中,使用单例是最好的方法吗?
  • @balajikommineni 这取决于很多事情。如果您是 RAII 的粉丝,假设您没有循环全局单例依赖项,那么全局单例会很好。关于哪种策略是正确的存在很多争论,但如果你问我,真正的问题是:你只会有一个 Reader 吗?一般来说,这就是单身人士的意义所在。只有一个、单一的、受控的访问类的点。就像在您的示例中一样,这非常方便。如果您不想要/不需要它,请考虑其他选项并选择有效的方法。也许可读性很重要,等等......
猜你喜欢
  • 2012-05-19
  • 2012-07-22
  • 2011-12-09
  • 2014-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多