C++,静态与命名空间与单例

发布于 2024-11-03 21:07:30 字数 591 浏览 1 评论 0原文

我已经在网上阅读了很多帖子和文章,但我找不到关于此的明确答案。

我有一些具有类似目的的函数,我希望将其置于全局范围之外。其中一些需要是公共的,其他应该是私有的(因为它们只是“公共”函数的辅助函数)。 此外,我不仅有函数,还有变量。它们仅被“私有”辅助函数需要,并且也应该是私有的。

现在有三种方法:

  • 制作一个所有东西都是静态的类(相反:潜在的“不能在没有对象的情况下调用成员函数” - 不是所有东西都需要是静态的)
  • 制作一个单例类(相反:我将需要该对象)
  • 制作一个命名空间(没有 private 关键字 - 那么我为什么要把它放在命名空间中呢?)

我应该采取什么方法?结合其中一些方法的可能方法?

我想到了类似的事情:

  1. 创建一个单例,静态函数使用单例对象的辅助函数(这可能吗?我仍在类中,但访问其类型的对象)
  2. 在程序开始时调用构造函数,初始化所有内容(-> 确保静态可以访问单例对象中的函数)
  3. 只能通过 MyClass::PublicStaticFunction() 访问公共函数,

谢谢。

I already read a lot of posts and articles all over the net, but I couldn't find a definite answer about this.

I have some functions with similar purposes that I want to have out of the global scope. Some of them need to be public, others should be private (because they are only helper functions for the "public" ones).
Additionally, I don't have only functions, but also variables. They are only needed by the "private" helper functions and should be private, too.

Now there are the three ways:

  • making a class with everything being static (contra: potential "Cannot call member function without object" - not everything needs to be static)
  • making a singleton class (contra: I WILL need the object)
  • making a namespace (no private keyword - why should I put it in a namespace at all, then?)

What would be the way to take for me? Possible way of combining some of these ways?

I thought of something like:

  1. making a singleton, the static functions use the helper function of the singleton object (is this possible? I'm still within the class, but accessing an object of it's type)
  2. constructor called at programm start, initializes everything (-> making sure the statics can access the functions from the singleton object)
  3. access the public functions only through MyClass::PublicStaticFunction()

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

瞳孔里扚悲伤 2024-11-10 21:07:30

如前所述,使用全局变量通常是不好的工程实践,除非绝对需要(例如映射硬件,但这种情况并不经常发生)。

在类似 Java 的语言中,您可以将所有内容存储在类中,但在 C++ 中则不必这样做,事实上,这里使用命名空间是一个更好的选择,只要:

  • 因为人们不会突然构建你的对象:目的是什么?
  • 因为没有为名称空间生成自省信息 (RTTI)

这是一个典型的实现:

// foo.h
#ifndef MYPROJECT_FOO_H_INCLUDED
#define MYPROJECT_FOO_H_INCLUDED

namespace myproject {
  void foo();
  void foomore();
}

#endif // MYPROJECT_FOO_H_INCLUDED

// foo.cpp
#include "myproject/foo.h"

namespace myproject {

namespace {
  typedef XXXX MyHelperType;

  void bar(MyHelperType& helper);
} // anonymous

void foo() {
  MyHelperType helper = /**/;
  bar(helper);
}

void foomore() {
  MyHelperType helper = /**/;
  bar(helper);
  bar(helper);
}
} // myproject

整齐地塞在源文件中的匿名名称空间是一个增强的 private 部分:客户端不仅无法使用其中的内容,而且他还可以使用它。甚至根本看不到它(因为它在源文件中),因此不依赖于它(它具有明确的 ABI 和编译时优势!)

As noted, using global variables is generally bad engineering practice, unless absolutely needed of course (mapping hardware for example, but that doesn't happen THAT often).

Stashing everything in a class is something you would do in a Java-like language, but in C++ you don't have to, and in fact using namespaces here is a superior alternative, if only:

  • because people won't suddenly build instances of your objects: to what end ?
  • because no introspection information (RTTI) is generated for namespaces

Here is a typical implementation:

// foo.h
#ifndef MYPROJECT_FOO_H_INCLUDED
#define MYPROJECT_FOO_H_INCLUDED

namespace myproject {
  void foo();
  void foomore();
}

#endif // MYPROJECT_FOO_H_INCLUDED

// foo.cpp
#include "myproject/foo.h"

namespace myproject {

namespace {
  typedef XXXX MyHelperType;

  void bar(MyHelperType& helper);
} // anonymous

void foo() {
  MyHelperType helper = /**/;
  bar(helper);
}

void foomore() {
  MyHelperType helper = /**/;
  bar(helper);
  bar(helper);
}
} // myproject

The anonymous namespace neatly tucked in a source file is an enhanced private section: not only the client cannot use what's inside, but he does not even see it at all (since it's in the source file) and thus do not depend on it (which has definite ABI and compile-time advantages!)

灵芸 2024-11-10 21:07:30

不要使其成为单例

对于不直接依赖于这些变量的公共辅助函数,请将它们设为非成员函数。把他们放在一个班级里没有任何好处。

对于其余的,将其作为普通非静态成员放入类中。如果您需要该类的单个可全局访问的实例,则创建一个(但不要使其成为单例,而只是全局的)。

否则,在需要时实例化它。

Don't make it a singleton

For public helper functions that don't directly depend on these variables, make them non-member functions. There's nothing gained by putting them in a class.

For the rest, put it in a class as normal non-static members. If you need a single globally accessible instance of the class, then create one (but don't make it a singleton, just a global).

Otherwise, instantiate it when needed.

假扮的天使 2024-11-10 21:07:30

执行此操作的经典 C 方法(似乎正是您想要的)是将公共函数声明放在头文件中,并将所有实现放在源文件中,使变量和非公共函数静态。否则,只需将其作为一个类来实现 - 我认为您在这里小题大做了。

The classic C way of doing this, which seems to be what you want, is to put the public function declarations in a header file, and all the implementation in source file, making the variables and non-public functions static. Otherwise just implement it as a class - I think you are making a bit of a mountain out of a molehill here.

小清晰的声音 2024-11-10 21:07:30

在全局范围内使用关键字static(使内容成为文件的本地内容)作为隐私替代品怎么样?

What about using a keyword static at global scope (making stuff local to the file) as a privacy substitute?

梦在深巷 2024-11-10 21:07:30

从您的描述来看,您似乎拥有彼此交互的方法和数据,换句话说,在我看来,您实际上想要一个非单例类来维护状态并提供对该状态的操作。将您的公共功能公开为接口,并将其他所有内容保持为私有。

然后您可以根据需要创建实例,您不必担心初始化顺序或线程问题(如果每个线程都有一个),并且只有需要访问的客户端才会有一个可以操作的对象。如果您确实只需要整个程序中的其中一个,您可以说在 main 中设置的全局指针或可能是 instance 方法,但它们都有自己的问题集。

From your description it looks like you have methods and data that interact with each other here, in other words it sounds to me like you actually want a non-singleton class to maintain the state and offer operations upon that state. Expose your public functions as the interface and keep everything else private.

Then you can create instance(s) as needed, you don't have to worry about init order or threading issues (if you have one per thread), and only clients that need access will have an object to operate upon. If you really need just one of these for the entire program you could get away say a global pointer that's set in main or possibly an instance method, but those come with their own sets of problems.

旧街凉风 2024-11-10 21:07:30

请记住,单例类的单例实例是有效实例,因此它完全能够成为非静态成员函数的接收者。如果将单例工厂公开为静态函数,然后将所有公共功能作为公共非静态成员函数,将私有功能作为私有非静态成员函数,则任何可以访问该类的人都可以通过简单地调用单例工厂来访问公共功能功能。

您没有描述您尝试包装的所有功能是否与证明位于同一类中的合理性相关,但如果是,则此方法可能有效。

如果您采用“类似 C”的方法并且仅使用顶级函数,则可以通过在 .cpp 文件而不是公开包含的 .h 文件中声明它们来将它们设为私有。如果您采用这种方法,您还应该将它们设为静态(或使用匿名名称空间)。

Remember that the singleton instance of a singleton class is a valid instance, so it is perfectly able to be the recipient of nonstatic member functions. If you expose your singleton factory as a static function then have all of your public functionality as public nonstatic member functions and your private functionality as private nonstatic member functions, anyone that can get at the class can access the public functionality by simply invoking the singleton factory function.

You don't describe whether all of the functionality you're trying to wrap up is as related as to justify being in the same class, but if it is, this approach might work.

If you take a "C-like" approach and just use top-level functions, you can make them private by declaring them in the .cpp file rather than the publicly-included .h file. You should also make them static (or use an anonymous namespace) if you take that approach.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文