静态成员类与普通的类似c的界面

问题描述:

嘿。
在阅读了关于Service Locator模式的here之后,它让我想到了只有静态成员的类真的是要走的路,或者如果正常的类似C的interace不会更合适。当他们甚至不需要它时,我看到人们一直在围绕着class关键字投掷。
实例与链接的网页拍摄静态成员类:静态成员类与普通的类似c的界面

class Locator 
{ 
public: 
    static IAudio* GetAudio() { return service_; } 

    static void Register(IAudio* service) 
    { 
     service_ = service; 
    } 

private: 
    static IAudio* service_; 
}; 

这里是一种人能做到这一点:

// in .h 
namespace Locator{ 
    IAudio* GetAudio(); 
    void Register(IAudio* service); 
} 

// in .cpp 
namespace Locator{ 
    namespace { 
     IAudio* service_; 
    } 

    IAudio* GetAudio() { 
     return service_; 
    } 
    void Register(IAudio* service) { 
     service_ = service; 
    } 
} 

两个例子可以称为完全相同的方式与Locator::GetAudio()Locator::Register(...)。 以上是其中之一吗?他们是一样的吗?有没有更好的方法来完成这个?还是仅仅是关于个人喜好?谢谢你的帮助。 :)

+0

这是一个可怕的模式。我不会接受任何推荐像这样的全局变量的网站的建议。 – Puppy 2011-02-12 10:19:36

+0

@Xeo:真正的问题:为什么在使用每个实例数据提供常规方法时使用全局状态? – 2011-02-12 11:21:43

您与命名空间的提案在维护轻微的弱点 - 如果你需要改变接口由于某些原因,你必须记住要更改这两个接口(.h)和执行(.cpp),或不匹配可能直到链接时间才被检测到。如果使用class,那么编译器可以检测到一个错误,例如一些参数不匹配。另一方面,由于您的案例中的实现(service_)仅出现在.cpp文件中,因此您可以更改定位器的私有实现,而不强制重新编译依赖于定位器的代码。 (通用的基于类的模式可以提供相同的封装。)

这些是相当小的差异。包含函数的公共名称空间几乎与仅具有静态成员函数的类完全相同。

使用类接口的一个很好的原因是一致性。

通常,在Locator类中将会有支持实现或使用共享数据的子类。因此,在整个代码库中使用一种方法(而不是为其静态数据组合名称空间和类)(因为某些实现可能会扩展或专门化该服务),因此更好(对很多人)。

很多人不喜欢处理静态数据。以上示例中的一些问题是:线程安全性,所有权和数据的生命周期。如果这些数据和实现仅限于类范围(而不是文件范围),则数据和实现可以更容易维护。这些问题随着程序复杂性的增长而增长 - 您发布的例子非常简单。

命名空间标签/别名更难以传递(与类型/ typedefs /模板参数相比)。如果你的接口类似,并且你使用了大量的泛型编程,或者你只是想实现测试,那么这很有用。