C++;单例定义 我对C++的单模式有一个小问题。 假设我有以下课程: namespace MyNameSpace { class Window_Singleton { private: static Window_Singleton instance; Window_Singleton(); /* Some more private stuff here */ public: static Window_Singleton *GetInstance(); ~Window_Singleton(); /* Some more public stuff here */ } } #define Window Window_Singleton.GetInstance()

C++;单例定义 我对C++的单模式有一个小问题。 假设我有以下课程: namespace MyNameSpace { class Window_Singleton { private: static Window_Singleton instance; Window_Singleton(); /* Some more private stuff here */ public: static Window_Singleton *GetInstance(); ~Window_Singleton(); /* Some more public stuff here */ } } #define Window Window_Singleton.GetInstance(),c++,singleton,C++,Singleton,我有了这个#定义,这样我就不必总是写MyNameSpace::Window\u Singleton.GetInstance().SomeMethod(),现在我可以使用更短的MyNameSpace::Window.SomeMethod() 但问题是:现在我无法在另一个命名空间中创建窗口类,因为我将在定义时遇到问题 是否有一种方法可以提供#define而不“破坏”我的命名空间。某种“名称空间本地”定义?由于宏是在编译之前展开的,预编译器不知道类、名称空间等内容。因此,如果您定义一个宏窗口,它将在任

我有了这个
#定义
,这样我就不必总是写
MyNameSpace::Window\u Singleton.GetInstance().SomeMethod()
,现在我可以使用更短的
MyNameSpace::Window.SomeMethod()

但问题是:现在我无法在另一个命名空间中创建窗口类,因为我将在定义时遇到问题


是否有一种方法可以提供
#define
而不“破坏”我的命名空间。某种“名称空间本地”定义?

由于宏是在编译之前展开的,预编译器不知道类、名称空间等内容。因此,如果您定义一个宏
窗口
,它将在任何地方使用

您可以定义一个函数:

inline Window_Singleton& Window(){
  return Window_Singleton.GetInstance();
}
然后写

Window().SomeMethod();

它基本上是一对额外的大括号,但它将使代码更加清晰。

由于宏在编译之前已展开,预编译器不知道类、名称空间等内容。因此,如果您定义一个宏
窗口
,它将在任何地方使用

您可以定义一个函数:

inline Window_Singleton& Window(){
  return Window_Singleton.GetInstance();
}
然后写

Window().SomeMethod();

它基本上是一对额外的大括号,但它将使代码更加清晰。

我强烈建议您不要在此处使用
#define
。实际上,它不会垃圾邮件的名称空间,但它可以完全搞乱任何代码,包括这个定义与难以找到的错误。例如,一旦定义了符号
窗口
,函数

Foo(Bar* Window){ /*...*/}
在某些情况下,您将很难发现此类错误。此外,它使您的代码更难阅读。如果我想调用静态函数来获取实例并调用方法,我希望代码如下所示:

Window_Singleton::GetInstance().SomeMethod();

看起来更像是调用某个全局实例的方法。我的意思是你可以用一个全球性的

Window_Singleton Window;
但正如我所理解的,你不想用一个全球的单身汉。总而言之:如果代码反映了您实际想要做的事情,那么代码很容易阅读。当调用静态方法看起来像是调用静态方法时,调用静态方法最容易混淆。如果你懒得打字,可以使用一些具有代码完整性的编辑器,但不要使用潜在危险的定义使你的代码更难阅读


PS:我必须提到,在我的评论中,我有点困惑<代码>#定义完全不知道名称空间。在编译器开始实际工作之前,在代码中替换它们。这就是为什么很难(如果不是不可能的话)将由
#define
引起的编译器错误与符号的定义位置联系起来。

我强烈建议您不要在此处使用
#define
。实际上,它不会垃圾邮件的名称空间,但它可以完全搞乱任何代码,包括这个定义与难以找到的错误。例如,一旦定义了符号
窗口
,函数

Foo(Bar* Window){ /*...*/}
在某些情况下,您将很难发现此类错误。此外,它使您的代码更难阅读。如果我想调用静态函数来获取实例并调用方法,我希望代码如下所示:

Window_Singleton::GetInstance().SomeMethod();

看起来更像是调用某个全局实例的方法。我的意思是你可以用一个全球性的

Window_Singleton Window;
但正如我所理解的,你不想用一个全球的单身汉。总而言之:如果代码反映了您实际想要做的事情,那么代码很容易阅读。当调用静态方法看起来像是调用静态方法时,调用静态方法最容易混淆。如果你懒得打字,可以使用一些具有代码完整性的编辑器,但不要使用潜在危险的定义使你的代码更难阅读

PS:我必须提到,在我的评论中,我有点困惑<代码>#定义完全不知道名称空间。在编译器开始实际工作之前,在代码中替换它们。这就是为什么很难(如果不是不可能的话)将
#defines
引起的编译器错误与符号的定义位置联系起来

有没有一种方法可以在不“破坏”我的命名空间的情况下提供#define。 某种“名称空间本地”定义

简短回答:没有


回答:宏没有作用域。这就是它们与其他C++特性的区别,不管是好是坏。


完整答案:

  • 如果可以避免,请不要使用宏
  • 如果使用任何宏,请使用
    ALL_CAPS
  • 根本不要使用单例模式
  • 简单的编写与代码质量无关
最后一点需要注意的是:如果您担心
MyNameSpace::Window\u Singleton.GetInstance().SomeMethod()
太长而无法阅读,那么我当然会对此表示同情。但这仍然不是让宏充斥代码的理由。您应该在本地范围内使用
use
,作为参考,并可能使用
auto
,以提高可读性。例如:

void f()
{
    using MyNameSpace::Window_Singleton;
    auto& window = Window_Singleton.GetInstance();

    window.SomeMethod();
}
有没有一种方法可以在不“破坏”我的命名空间的情况下提供#define。 某种“名称空间本地”定义

简短回答:没有


回答:宏没有作用域。这就是它们与其他C++特性的区别,不管是好是坏。


完整答案:

  • 如果可以避免,请不要使用宏
  • 如果使用任何宏,请使用
    ALL_CAPS
  • 根本不要使用单例模式
  • 简单的编写与代码质量无关
最后一点需要注意的是:如果您担心
MyNameSpace::Window\u Singleton.GetInstance().SomeMethod()
太长而无法阅读,那么我当然会对此表示同情。但这仍然不是让宏充斥代码的理由。您应该在本地范围内使用
use
,作为参考,并可能使用
auto
,以提高可读性。例如:

void f()
{
    using MyNameSpace::Window_Singleton;
    auto& window = Window_Singleton.GetInstance();

    window.SomeMethod();
}

我认为没有一种方法可以使用宏,这就是ign