如何在c++中创建静态类?

时间:2023-01-13 09:07:58

How do you create a static class in C++? I should be able to do something like:

如何在c++中创建静态类?我应该能够做到:

cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;

Assuming I created the BitParser class. What would the BitParser class definition look like?

假设我创建了位分析器类。位分析器类定义是什么样子的?

12 个解决方案

#1


228  

If you're looking for a way of applying the "static" keyword to a class, like you can in C# for example, then you won't be able to without using Managed C++.

如果您正在寻找将“static”关键字应用于类的方法,例如您可以在c#中这样做,那么您将无法不使用托管c++。

But the looks of your sample, you just need to create a public static method on your BitParser object. Like so:

但是您的示例的外观,您只需要在BitParser对象上创建一个公共静态方法。像这样:

BitParser.h

BitParser.h

class BitParser
{
 public:
  static bool getBitAt(int buffer, int bitIndex);

  // ...lots of great stuff

 private:
  // Disallow creating an instance of this object
  BitParser() {}
};

BitParser.cpp

BitParser.cpp

bool BitParser::getBitAt(int buffer, int bitIndex)
{
  bool isBitSet = false;
  // .. determine if bit is set
  return isBitSet;
}

You can use this code to call the method in the same way as your example code.

您可以使用此代码以与示例代码相同的方式调用该方法。

Hope that helps! Cheers.

希望会有帮助!欢呼。

#2


207  

Consider Matt Price's solution.

马特考虑价格的解决方案。

  1. In C++, a "static class" has no meaning. The nearest thing is a class with only static methods and members.
  2. 在c++中,“静态类”没有任何意义。最近的东西是一个只有静态方法和成员的类。
  3. Using static methods will only limit you.
  4. 使用静态方法只会限制您。

What you want is, expressed in C++ semantics, to put your function (for it is a function) in a namespace.

您需要的是,用c++语义表示,将函数(因为它是一个函数)放在一个名称空间中。

Edit 2011-11-11

There is no "static class" in C++. The nearest concept would be a class with only static methods. For example:

c++中没有“静态类”。最近的概念是只有静态方法的类。例如:

// header
class MyClass
{
   public :
      static void myMethod() ;
} ;

// source
void MyClass::myMethod()
{
   // etc.
}

But you must remember that "static classes" are hacks in the Java-like kind of languages (e.g. C#) that are unable to have non-member functions, so they have instead to move them inside classes as static methods.

但是您必须记住,“静态类”是类java语言(例如c#)中的hack,它们不能具有非成员函数,因此它们必须将它们作为静态方法在类中移动。

In C++, what you really want is a non-member function that you'll declare in a namespace:

在c++中,您真正想要的是一个非成员函数,您将在名称空间中声明:

// header
namespace MyNamespace
{
   static void myMethod() ;
}

// source
namespace MyNamespace
{
   void myMethod()
   {
      // etc.
   }
}

Why is that?

In C++, the namespace is more powerful than classes for the "Java static method" pattern, because:

在c++中,命名空间比“Java静态方法”模式的类更强大,因为:

  • static methods have access to the classes private symbols
  • 静态方法可以访问类私有符号
  • private static methods are still visible (if inaccessible) to everyone, which breaches somewhat the encapsulation
  • 私有静态方法仍然对每个人可见(如果不可访问),这在一定程度上违背了封装
  • static methods cannot be forward-declared
  • 静态方法不能向前声明
  • static methods cannot be overloaded by the class user without modifying the library header
  • 静态方法不能被类用户重载,而无需修改库头。
  • there is nothing that can be done by a static method that can't be done better than a (possibly friend) non-member function in the same namespace
  • 静态方法所做的事情没有什么比在同一个名称空间中(可能是朋友)非成员函数更好的了
  • namespaces have their own semantics (they can be combined, they can be anonymous, etc.)
  • 名称空间有它们自己的语义(它们可以组合起来,可以是匿名的,等等)。
  • etc.
  • 等。

Conclusion: Do not copy/paste that Java/C#'s pattern in C++. In Java/C#, the pattern is mandatory. But in C++, it is bad style.

结论:不要在c++中复制/粘贴Java/ c#的模式。在Java/ c#中,模式是强制性的。但在c++中,这是一种糟糕的风格。

Edit 2010-06-10

There was an argument in favor to the static method because sometimes, one needs to use a static private member variable.

有一个支持静态方法的参数,因为有时需要使用静态私有成员变量。

I disagree somewhat, as show below:

我有些不同意,如下所示:

The "Static private member" solution

// HPP

class Foo
{
   public :
      void barA() ;
   private :
      void barB() ;
      static std::string myGlobal ;
} ;

First, myGlobal is called myGlobal because it is still a global private variable. A look at the CPP source will clarify that:

首先,myGlobal被称为myGlobal,因为它仍然是一个全局私有变量。看看CPP的来源就会明白:

// CPP
std::string Foo::myGlobal ; // You MUST declare it in a CPP

void Foo::barA()
{
   // I can access Foo::myGlobal
}

void Foo::barB()
{
   // I can access Foo::myGlobal, too
}

void barC()
{
   // I CAN'T access Foo::myGlobal !!!
}

At first sight, the fact the free function barC can't access Foo::myGlobal seems a good thing from an encapsulation viewpoint... It's cool because someone looking at the HPP won't be able (unless resorting to sabotage) to access Foo::myGlobal.

乍一看,*函数barC不能访问Foo::myGlobal从封装的角度来看似乎是一件好事……这很酷,因为看着HPP的人无法(除非通过破坏)访问Foo: myGlobal。

But if you look at it closely, you'll find that it is a colossal mistake: Not only your private variable must still be declared in the HPP (and so, visible to all the world, despite being private), but you must declare in the same HPP all (as in ALL) functions that will be authorized to access it !!!

但如果你仔细看,你会发现这是一个巨大的错误:不仅您的私有变量仍然必须宣布在高压泵(可见全世界,尽管是私有的),但是你必须声明在同一个HPP所有()函数将授权访问它! ! !

So using a private static member is like walking outside in the nude with the list of your lovers tattooed on your skin : No one is authorized to touch, but everyone is able to peek at. And the bonus: Everyone can have the names of those authorized to play with your privies.

因此,使用一个私有的静态成员就像裸着走在外面,把你的爱人名单纹在你的皮肤上:没有人被授权触摸,但是每个人都可以偷看。还有一个好处:每个人都可以有被授权玩你的特权的人的名字。

private indeed... :-D

私人确实……:- d

The "Anonymous namespaces" solution

Anonymous namespaces will have the advantage of making things private really private.

匿名名称空间的优点是使事物变得私有。

First, the HPP header

首先,高压泵头

// HPP

namespace Foo
{
   void barA() ;
}

Just to be sure you remarked: There is no useless declaration of barB nor myGlobal. Which means that no one reading the header knows what's hidden behind barA.

我只是想确认一下,你说过:barB和myGlobal都不是毫无用处的宣言。也就是说,读标题的人都不知道巴拉背后隐藏着什么。

Then, the CPP:

然后,CPP:

// CPP
namespace Foo
{
   namespace
   {
      std::string myGlobal ;

      void Foo::barB()
      {
         // I can access Foo::myGlobal
      }
   }

   void barA()
   {
      // I can access myGlobal, too
   }
}

void barC()
{
   // I STILL CAN'T access myGlobal !!!
}

As you can see, like the so-called "static class" declaration, fooA and fooB are still able to access myGlobal. But no one else can. And no one else outside this CPP knows fooB and myGlobal even exist!

如您所见,像所谓的“静态类”声明一样,fooA和fooB仍然能够访问myGlobal。但没有人能做到。除了CPP,没有人知道fooB和myGlobal !

Unlike the "static class" walking on the nude with her address book tattooed on her skin the "anonymous" namespace is fully clothed, which seems quite better encapsulated AFAIK.

与“静态课堂”不同的是,她的地址簿在她的皮肤上纹上了“匿名”的字样,而“匿名”的名称空间是完全覆盖的,这似乎是更好的封装了AFAIK。

Does it really matter?

Unless the users of your code are saboteurs (I'll let you, as an exercise, find how one can access to the private part of a public class using a dirty behaviour-undefined hack...), what's private is private, even if it is visible in the private section of a class declared in a header.

除非用户代码的破坏者(我会让你,作为练习,找到如何可以访问一个公共类的私有部分使用一个肮脏的behaviour-undefined黑客…),私人的是私人的,即使是在一个类的私有部分中声明一个头。

Still, if you need to add another "private function" with access to the private member, you still must declare it to all the world by modifying the header, which is a paradox as far as I am concerned: If I change the implementation of my code (the CPP part), then the interface (the HPP part) should NOT change. Quoting Leonidas : "This is ENCAPSULATION!"

不过,如果你需要添加另一个“私人函数”访问私有成员,你仍然必须声明全世界通过修改标题,这是一个悖论就我而言:如果我改变我的代码的实现(CPP)的一部分,那么接口(HPP部分)应该不会改变。引用Leonidas的话:“这是封装!”

Edit 2014-09-20

When are classes static methods are actually better than namespaces with non-member functions?

什么时候类静态方法比具有非成员函数的名称空间更好?

When you need to group together functions and feed that group to a template:

当您需要将函数分组,并将该分组提供给模板时:

namespace alpha
{
   void foo() ;
   void bar() ;
}

struct Beta
{
   static void foo() ;
   static void bar() ;
};

template <typename T>
struct Gamma
{
   void foobar()
   {
      T::foo() ;
      T::bar() ;
   }
};

Gamma<alpha> ga ; // compilation error
Gamma<Beta> gb ;  // ok
gb.foobar() ;     // ok !!!

Because, if a class can be a template parameter, a namespaces cannot.

因为,如果一个类可以是模板参数,那么命名空间就不能。

#3


57  

You can also create a free function in a namespace:

您还可以在名称空间中创建一个*函数:

In BitParser.h

在BitParser.h

namespace BitParser
{
    bool getBitAt(int buffer, int bitIndex);
}

In BitParser.cpp

在BitParser.cpp

namespace BitParser
{
    bool getBitAt(int buffer, int bitIndex)
    {
        //get the bit :)
    }
}

In general this would be the preferred way to write the code. When there's no need for an object don't use a class.

一般来说,这是编写代码的首选方式。当不需要对象时,不要使用类。

#4


12  

If you're looking for a way of applying the "static" keyword to a class, like you can in C# for example

如果您正在寻找将“static”关键字应用到类的方法,例如您可以在c#中这样做

static classes are just the compiler hand-holding you and stopping you from writing any instance methods/variables.

静态类只是编译器控制您并阻止您编写任何实例方法/变量。

If you just write a normal class without any instance methods/variables, it's the same thing, and this is what you'd do in C++

如果你只写一个普通的类,没有任何实例方法/变量,这是一样的,这就是你在c++中要做的

#5


11  

In C++ you want to create a static function of a class (not a static class).

在c++中,您希望创建一个类的静态函数(而不是静态类)。

class BitParser {
public:
  ...
  static ... getBitAt(...) {
  }
};

You should then be able to call the function using BitParser::getBitAt() without instantiating an object which I presume is the desired result.

然后,您应该能够使用BitParser::getBitAt()调用函数,而无需实例化一个我认为是理想结果的对象。

#6


10  

Can I write something like static class?

我可以写一些静态类吗?

No, according to the C++11 N3337 standard draft Annex C 7.1.1:

不,根据C+ 11 N3337标准草案附件C 7.1.1:

Change: In C ++, the static or extern specifiers can only be applied to names of objects or functions. Using these specifiers with type declarations is illegal in C ++. In C, these specifiers are ignored when used on type declarations. Example:

更改:在c++中,静态或外部说明符只能应用于对象或函数的名称。在c++中,在类型声明中使用这些说明符是非法的。在C中,当在类型声明中使用时,这些说明符会被忽略。例子:

static struct S {    // valid C, invalid in C++
  int i;
};

Rationale: Storage class specifiers don’t have any meaning when associated with a type. In C ++, class members can be declared with the static storage class specifier. Allowing storage class specifiers on type declarations could render the code confusing for users.

基本原理:当与类型关联时,存储类说明符没有任何意义。在c++中,可以使用静态存储类说明符声明类成员。允许在类型声明上使用存储类说明符可能会使用户对代码感到困惑。

And like struct, class is also a type declaration.

和struct一样,类也是一种类型声明。

The same can be deduced by walking the syntax tree in Annex A.

通过遍历附录A中的语法树可以推断出这一点。

It is interesting to note that static struct was legal in C, but had no effect: Why and when to use static structures in C programming?

有趣的是,静态结构在C语言中是合法的,但是没有影响:为什么在C编程中使用静态结构?

#7


5  

You 'can' have a static class in C++, as mentioned before, a static class is one that does not have any objects of it instantiated it. In C++, this can be obtained by declaring the constructor/destructor as private. End result is the same.

在c++中可以有一个静态类,如前所述,静态类是一个没有实例化它的任何对象的类。在c++中,可以通过将构造函数/析构函数声明为private来实现这一点。最终结果是一样的。

#8


4  

In Managed C++, static class syntax is:-

在托管c++中,静态类语法是:-

public ref class BitParser abstract sealed
{
    public:
        static bool GetBitAt(...)
        {
            ...
        }
}

... better late than never...

…迟到总比不到好…

#9


3  

This is similar to C#'s way of doing it in C++

这类似于c#在c++中使用的方法

In C# file.cs you can have private var inside a public function. When in another file you can use it by calling the namespace with the function as in:

在c#文件中。在公共函数中可以有私有var。在另一个文件中,可以通过调用具有如下函数的名称空间来使用:

MyNamespace.Function(blah);

Here's how to imp the same in C++:

下面是如何在c++中实现同样的功能:

SharedModule.h

SharedModule.h

class TheDataToBeHidden
{
  public:
    static int _var1;
    static int _var2;
};

namespace SharedData
{
  void SetError(const char *Message, const char *Title);
  void DisplayError(void);
}

SharedModule.cpp

SharedModule.cpp

//Init the data (Link error if not done)
int TheDataToBeHidden::_var1 = 0;
int TheDataToBeHidden::_var2 = 0;


//Implement the namespace
namespace SharedData
{
  void SetError(const char *Message, const char *Title)
  {
    //blah using TheDataToBeHidden::_var1, etc
  }

  void DisplayError(void)
  {
    //blah
  }
}

OtherFile.h

OtherFile.h

#include "SharedModule.h"

OtherFile.cpp

OtherFile.cpp

//Call the functions using the hidden variables
SharedData::SetError("Hello", "World");
SharedData::DisplayError();

#10


3  

Unlike other managed programming language, "static class" has NO meaning in C++. You can make use of static member function.

与其他托管编程语言不同,“静态类”在c++中没有任何意义。您可以使用静态成员函数。

#11


1  

As it has been noted here, a better way of achieving this in C++ might be using namespaces. But since no one has mentioned the final keyword here, I'm posting what a direct equivalent of static class from C# would look like in C++11 or later:

正如这里提到的,使用c++实现这一点的更好方法可能是使用名称空间。但是由于这里没有人提到最后的关键字,我在这里发布了c#的静态类在c++ 11或更晚的时候会是什么样子的:

class BitParser final
{
public:
  BitParser() = delete;

  static bool GetBitAt(int buffer, int pos);
};

bool BitParser::GetBitAt(int buffer, int pos)
{
  // your code
}

#12


0  

One case where namespaces may not be so useful for achieving "static classes" is when using these classes to achieve composition over inheritance. Namespaces cannot be friends of classes and so cannot access private members of a class.

名称空间对于实现“静态类”可能没有那么有用的一个例子是,当使用这些类来实现复合而不是继承时。名称空间不能是类的朋友,因此不能访问类的私有成员。

class Class {
 public:
  void foo() { Static::bar(*this); }    

 private:
  int member{0};
  friend class Static;
};    

class Static {
 public:
  template <typename T>
  static void bar(T& t) {
    t.member = 1;
  }
};

#1


228  

If you're looking for a way of applying the "static" keyword to a class, like you can in C# for example, then you won't be able to without using Managed C++.

如果您正在寻找将“static”关键字应用于类的方法,例如您可以在c#中这样做,那么您将无法不使用托管c++。

But the looks of your sample, you just need to create a public static method on your BitParser object. Like so:

但是您的示例的外观,您只需要在BitParser对象上创建一个公共静态方法。像这样:

BitParser.h

BitParser.h

class BitParser
{
 public:
  static bool getBitAt(int buffer, int bitIndex);

  // ...lots of great stuff

 private:
  // Disallow creating an instance of this object
  BitParser() {}
};

BitParser.cpp

BitParser.cpp

bool BitParser::getBitAt(int buffer, int bitIndex)
{
  bool isBitSet = false;
  // .. determine if bit is set
  return isBitSet;
}

You can use this code to call the method in the same way as your example code.

您可以使用此代码以与示例代码相同的方式调用该方法。

Hope that helps! Cheers.

希望会有帮助!欢呼。

#2


207  

Consider Matt Price's solution.

马特考虑价格的解决方案。

  1. In C++, a "static class" has no meaning. The nearest thing is a class with only static methods and members.
  2. 在c++中,“静态类”没有任何意义。最近的东西是一个只有静态方法和成员的类。
  3. Using static methods will only limit you.
  4. 使用静态方法只会限制您。

What you want is, expressed in C++ semantics, to put your function (for it is a function) in a namespace.

您需要的是,用c++语义表示,将函数(因为它是一个函数)放在一个名称空间中。

Edit 2011-11-11

There is no "static class" in C++. The nearest concept would be a class with only static methods. For example:

c++中没有“静态类”。最近的概念是只有静态方法的类。例如:

// header
class MyClass
{
   public :
      static void myMethod() ;
} ;

// source
void MyClass::myMethod()
{
   // etc.
}

But you must remember that "static classes" are hacks in the Java-like kind of languages (e.g. C#) that are unable to have non-member functions, so they have instead to move them inside classes as static methods.

但是您必须记住,“静态类”是类java语言(例如c#)中的hack,它们不能具有非成员函数,因此它们必须将它们作为静态方法在类中移动。

In C++, what you really want is a non-member function that you'll declare in a namespace:

在c++中,您真正想要的是一个非成员函数,您将在名称空间中声明:

// header
namespace MyNamespace
{
   static void myMethod() ;
}

// source
namespace MyNamespace
{
   void myMethod()
   {
      // etc.
   }
}

Why is that?

In C++, the namespace is more powerful than classes for the "Java static method" pattern, because:

在c++中,命名空间比“Java静态方法”模式的类更强大,因为:

  • static methods have access to the classes private symbols
  • 静态方法可以访问类私有符号
  • private static methods are still visible (if inaccessible) to everyone, which breaches somewhat the encapsulation
  • 私有静态方法仍然对每个人可见(如果不可访问),这在一定程度上违背了封装
  • static methods cannot be forward-declared
  • 静态方法不能向前声明
  • static methods cannot be overloaded by the class user without modifying the library header
  • 静态方法不能被类用户重载,而无需修改库头。
  • there is nothing that can be done by a static method that can't be done better than a (possibly friend) non-member function in the same namespace
  • 静态方法所做的事情没有什么比在同一个名称空间中(可能是朋友)非成员函数更好的了
  • namespaces have their own semantics (they can be combined, they can be anonymous, etc.)
  • 名称空间有它们自己的语义(它们可以组合起来,可以是匿名的,等等)。
  • etc.
  • 等。

Conclusion: Do not copy/paste that Java/C#'s pattern in C++. In Java/C#, the pattern is mandatory. But in C++, it is bad style.

结论:不要在c++中复制/粘贴Java/ c#的模式。在Java/ c#中,模式是强制性的。但在c++中,这是一种糟糕的风格。

Edit 2010-06-10

There was an argument in favor to the static method because sometimes, one needs to use a static private member variable.

有一个支持静态方法的参数,因为有时需要使用静态私有成员变量。

I disagree somewhat, as show below:

我有些不同意,如下所示:

The "Static private member" solution

// HPP

class Foo
{
   public :
      void barA() ;
   private :
      void barB() ;
      static std::string myGlobal ;
} ;

First, myGlobal is called myGlobal because it is still a global private variable. A look at the CPP source will clarify that:

首先,myGlobal被称为myGlobal,因为它仍然是一个全局私有变量。看看CPP的来源就会明白:

// CPP
std::string Foo::myGlobal ; // You MUST declare it in a CPP

void Foo::barA()
{
   // I can access Foo::myGlobal
}

void Foo::barB()
{
   // I can access Foo::myGlobal, too
}

void barC()
{
   // I CAN'T access Foo::myGlobal !!!
}

At first sight, the fact the free function barC can't access Foo::myGlobal seems a good thing from an encapsulation viewpoint... It's cool because someone looking at the HPP won't be able (unless resorting to sabotage) to access Foo::myGlobal.

乍一看,*函数barC不能访问Foo::myGlobal从封装的角度来看似乎是一件好事……这很酷,因为看着HPP的人无法(除非通过破坏)访问Foo: myGlobal。

But if you look at it closely, you'll find that it is a colossal mistake: Not only your private variable must still be declared in the HPP (and so, visible to all the world, despite being private), but you must declare in the same HPP all (as in ALL) functions that will be authorized to access it !!!

但如果你仔细看,你会发现这是一个巨大的错误:不仅您的私有变量仍然必须宣布在高压泵(可见全世界,尽管是私有的),但是你必须声明在同一个HPP所有()函数将授权访问它! ! !

So using a private static member is like walking outside in the nude with the list of your lovers tattooed on your skin : No one is authorized to touch, but everyone is able to peek at. And the bonus: Everyone can have the names of those authorized to play with your privies.

因此,使用一个私有的静态成员就像裸着走在外面,把你的爱人名单纹在你的皮肤上:没有人被授权触摸,但是每个人都可以偷看。还有一个好处:每个人都可以有被授权玩你的特权的人的名字。

private indeed... :-D

私人确实……:- d

The "Anonymous namespaces" solution

Anonymous namespaces will have the advantage of making things private really private.

匿名名称空间的优点是使事物变得私有。

First, the HPP header

首先,高压泵头

// HPP

namespace Foo
{
   void barA() ;
}

Just to be sure you remarked: There is no useless declaration of barB nor myGlobal. Which means that no one reading the header knows what's hidden behind barA.

我只是想确认一下,你说过:barB和myGlobal都不是毫无用处的宣言。也就是说,读标题的人都不知道巴拉背后隐藏着什么。

Then, the CPP:

然后,CPP:

// CPP
namespace Foo
{
   namespace
   {
      std::string myGlobal ;

      void Foo::barB()
      {
         // I can access Foo::myGlobal
      }
   }

   void barA()
   {
      // I can access myGlobal, too
   }
}

void barC()
{
   // I STILL CAN'T access myGlobal !!!
}

As you can see, like the so-called "static class" declaration, fooA and fooB are still able to access myGlobal. But no one else can. And no one else outside this CPP knows fooB and myGlobal even exist!

如您所见,像所谓的“静态类”声明一样,fooA和fooB仍然能够访问myGlobal。但没有人能做到。除了CPP,没有人知道fooB和myGlobal !

Unlike the "static class" walking on the nude with her address book tattooed on her skin the "anonymous" namespace is fully clothed, which seems quite better encapsulated AFAIK.

与“静态课堂”不同的是,她的地址簿在她的皮肤上纹上了“匿名”的字样,而“匿名”的名称空间是完全覆盖的,这似乎是更好的封装了AFAIK。

Does it really matter?

Unless the users of your code are saboteurs (I'll let you, as an exercise, find how one can access to the private part of a public class using a dirty behaviour-undefined hack...), what's private is private, even if it is visible in the private section of a class declared in a header.

除非用户代码的破坏者(我会让你,作为练习,找到如何可以访问一个公共类的私有部分使用一个肮脏的behaviour-undefined黑客…),私人的是私人的,即使是在一个类的私有部分中声明一个头。

Still, if you need to add another "private function" with access to the private member, you still must declare it to all the world by modifying the header, which is a paradox as far as I am concerned: If I change the implementation of my code (the CPP part), then the interface (the HPP part) should NOT change. Quoting Leonidas : "This is ENCAPSULATION!"

不过,如果你需要添加另一个“私人函数”访问私有成员,你仍然必须声明全世界通过修改标题,这是一个悖论就我而言:如果我改变我的代码的实现(CPP)的一部分,那么接口(HPP部分)应该不会改变。引用Leonidas的话:“这是封装!”

Edit 2014-09-20

When are classes static methods are actually better than namespaces with non-member functions?

什么时候类静态方法比具有非成员函数的名称空间更好?

When you need to group together functions and feed that group to a template:

当您需要将函数分组,并将该分组提供给模板时:

namespace alpha
{
   void foo() ;
   void bar() ;
}

struct Beta
{
   static void foo() ;
   static void bar() ;
};

template <typename T>
struct Gamma
{
   void foobar()
   {
      T::foo() ;
      T::bar() ;
   }
};

Gamma<alpha> ga ; // compilation error
Gamma<Beta> gb ;  // ok
gb.foobar() ;     // ok !!!

Because, if a class can be a template parameter, a namespaces cannot.

因为,如果一个类可以是模板参数,那么命名空间就不能。

#3


57  

You can also create a free function in a namespace:

您还可以在名称空间中创建一个*函数:

In BitParser.h

在BitParser.h

namespace BitParser
{
    bool getBitAt(int buffer, int bitIndex);
}

In BitParser.cpp

在BitParser.cpp

namespace BitParser
{
    bool getBitAt(int buffer, int bitIndex)
    {
        //get the bit :)
    }
}

In general this would be the preferred way to write the code. When there's no need for an object don't use a class.

一般来说,这是编写代码的首选方式。当不需要对象时,不要使用类。

#4


12  

If you're looking for a way of applying the "static" keyword to a class, like you can in C# for example

如果您正在寻找将“static”关键字应用到类的方法,例如您可以在c#中这样做

static classes are just the compiler hand-holding you and stopping you from writing any instance methods/variables.

静态类只是编译器控制您并阻止您编写任何实例方法/变量。

If you just write a normal class without any instance methods/variables, it's the same thing, and this is what you'd do in C++

如果你只写一个普通的类,没有任何实例方法/变量,这是一样的,这就是你在c++中要做的

#5


11  

In C++ you want to create a static function of a class (not a static class).

在c++中,您希望创建一个类的静态函数(而不是静态类)。

class BitParser {
public:
  ...
  static ... getBitAt(...) {
  }
};

You should then be able to call the function using BitParser::getBitAt() without instantiating an object which I presume is the desired result.

然后,您应该能够使用BitParser::getBitAt()调用函数,而无需实例化一个我认为是理想结果的对象。

#6


10  

Can I write something like static class?

我可以写一些静态类吗?

No, according to the C++11 N3337 standard draft Annex C 7.1.1:

不,根据C+ 11 N3337标准草案附件C 7.1.1:

Change: In C ++, the static or extern specifiers can only be applied to names of objects or functions. Using these specifiers with type declarations is illegal in C ++. In C, these specifiers are ignored when used on type declarations. Example:

更改:在c++中,静态或外部说明符只能应用于对象或函数的名称。在c++中,在类型声明中使用这些说明符是非法的。在C中,当在类型声明中使用时,这些说明符会被忽略。例子:

static struct S {    // valid C, invalid in C++
  int i;
};

Rationale: Storage class specifiers don’t have any meaning when associated with a type. In C ++, class members can be declared with the static storage class specifier. Allowing storage class specifiers on type declarations could render the code confusing for users.

基本原理:当与类型关联时,存储类说明符没有任何意义。在c++中,可以使用静态存储类说明符声明类成员。允许在类型声明上使用存储类说明符可能会使用户对代码感到困惑。

And like struct, class is also a type declaration.

和struct一样,类也是一种类型声明。

The same can be deduced by walking the syntax tree in Annex A.

通过遍历附录A中的语法树可以推断出这一点。

It is interesting to note that static struct was legal in C, but had no effect: Why and when to use static structures in C programming?

有趣的是,静态结构在C语言中是合法的,但是没有影响:为什么在C编程中使用静态结构?

#7


5  

You 'can' have a static class in C++, as mentioned before, a static class is one that does not have any objects of it instantiated it. In C++, this can be obtained by declaring the constructor/destructor as private. End result is the same.

在c++中可以有一个静态类,如前所述,静态类是一个没有实例化它的任何对象的类。在c++中,可以通过将构造函数/析构函数声明为private来实现这一点。最终结果是一样的。

#8


4  

In Managed C++, static class syntax is:-

在托管c++中,静态类语法是:-

public ref class BitParser abstract sealed
{
    public:
        static bool GetBitAt(...)
        {
            ...
        }
}

... better late than never...

…迟到总比不到好…

#9


3  

This is similar to C#'s way of doing it in C++

这类似于c#在c++中使用的方法

In C# file.cs you can have private var inside a public function. When in another file you can use it by calling the namespace with the function as in:

在c#文件中。在公共函数中可以有私有var。在另一个文件中,可以通过调用具有如下函数的名称空间来使用:

MyNamespace.Function(blah);

Here's how to imp the same in C++:

下面是如何在c++中实现同样的功能:

SharedModule.h

SharedModule.h

class TheDataToBeHidden
{
  public:
    static int _var1;
    static int _var2;
};

namespace SharedData
{
  void SetError(const char *Message, const char *Title);
  void DisplayError(void);
}

SharedModule.cpp

SharedModule.cpp

//Init the data (Link error if not done)
int TheDataToBeHidden::_var1 = 0;
int TheDataToBeHidden::_var2 = 0;


//Implement the namespace
namespace SharedData
{
  void SetError(const char *Message, const char *Title)
  {
    //blah using TheDataToBeHidden::_var1, etc
  }

  void DisplayError(void)
  {
    //blah
  }
}

OtherFile.h

OtherFile.h

#include "SharedModule.h"

OtherFile.cpp

OtherFile.cpp

//Call the functions using the hidden variables
SharedData::SetError("Hello", "World");
SharedData::DisplayError();

#10


3  

Unlike other managed programming language, "static class" has NO meaning in C++. You can make use of static member function.

与其他托管编程语言不同,“静态类”在c++中没有任何意义。您可以使用静态成员函数。

#11


1  

As it has been noted here, a better way of achieving this in C++ might be using namespaces. But since no one has mentioned the final keyword here, I'm posting what a direct equivalent of static class from C# would look like in C++11 or later:

正如这里提到的,使用c++实现这一点的更好方法可能是使用名称空间。但是由于这里没有人提到最后的关键字,我在这里发布了c#的静态类在c++ 11或更晚的时候会是什么样子的:

class BitParser final
{
public:
  BitParser() = delete;

  static bool GetBitAt(int buffer, int pos);
};

bool BitParser::GetBitAt(int buffer, int pos)
{
  // your code
}

#12


0  

One case where namespaces may not be so useful for achieving "static classes" is when using these classes to achieve composition over inheritance. Namespaces cannot be friends of classes and so cannot access private members of a class.

名称空间对于实现“静态类”可能没有那么有用的一个例子是,当使用这些类来实现复合而不是继承时。名称空间不能是类的朋友,因此不能访问类的私有成员。

class Class {
 public:
  void foo() { Static::bar(*this); }    

 private:
  int member{0};
  friend class Static;
};    

class Static {
 public:
  template <typename T>
  static void bar(T& t) {
    t.member = 1;
  }
};