1

在 C++ 中,可以在不定义该类的对象的情况下使用类的数据成员,方法是将公共部分中的数据成员定义为static变量,如下面的代码示例所示。问题是,我为什么/什么时候想这样做?我该怎么做?

class ttime{
public:
    ttime(int h=0, int m=0, int s=0):hour(h), minute(m), second(s){}   //constructor with default intialization
    int& warning(){return hour;}
    void display()const{cout<<hour<<"\t";}
    static int hello; 
    ~ttime(){}

private:
    int hour;
    int minute;
    int second;
};


main()
{
    ttime:: hello=11310; //Is this the way to use hello without creating an object of the class?
    cout << ttime:: hello;

    ttime hi(9); 
    hi.display();
    hi.warning()++;//the user is able to modify your class's private data, which is really bad! You should not be doing this!
    hi.display();
}
4

5 回答 5

2

将类成员变量声明为static本质上使其成为由该类的所有实例共享的单例对象。这对于计数器、信号量和锁以及需要由其他类成员共享的其他类型的数据非常有用。

声明它public使该类的所有用户都可以访问它。但是,允许类变量由类外的函数修改通常是一个坏主意。

const另一方面,声明它是为类提供公共可读常量的常用方法。

例子

你的图书馆类:

class Foo
{
public:
    // Version number of this code
    static const int    VERSION = 1;

private:
    // Counts the number of active Foo objects
    static int          counter = 0;

public:
    // Constructor
    Foo()
    {
        counter++;     // Bump the instance counter
        ...
    }

    // Destructor
    ~Foo()
    {
        counter--;     // Adjust the counter
        ...
    }
};

您图书馆的一些客户:

class Bar
{
public:
    // Constructor
    Bar()
    {
        // Check the Foo library version
        if (Foo::VERSION > 1)
            std::cerr << "Wrong version of class Foo, need version 1";
        ...
    }
};

在这个例子中,VERSION是类的一个静态常量,在这种情况下,它会通知外界这个类中包含什么版本的代码。它通过语法访问Foo::VERSION

counter另一方面,静态变量是类私有的,因此只有 的成员函数Foo才能访问它。在这种情况下,它被用作活动Foo对象数量的计数器。

于 2015-02-11T18:49:31.403 回答
1

尽管最初不是为此目的而发明的,但static constexpr数据成员structs是模板元编程的支柱。只需查看limits标准库头文件作为一个简单的示例。

例如,我们可以围绕内置sizeof运算符定义一个包装器。虽然它本身没什么用,但它希望能给出正确的想法。

#include <iostream>

template<typename T>
struct Calipers
{
  static constexpr auto size = sizeof(T);
};

int
main()
{
  std::cout << "short:   " << Calipers<short>::size   << "\n";
  std::cout << "int:     " << Calipers<int>::size     << "\n";
  std::cout << "long:    " << Calipers<long>::size    << "\n";
  std::cout << "float:   " << Calipers<float>::size   << "\n";
  std::cout << "double:  " << Calipers<double>::size  << "\n";
}

可能的输出:

short:   2
int:     4
long:    8
float:   4
double:  8
于 2015-02-11T19:01:25.407 回答
1

如前所述,静态成员变量作为“全局”变量工作,但在类命名空间内。所以它对于对象之间的计数器或共享资源很有用。

在“public static”修饰符的情况下,很容易看到它在库中用于提供对常量和通用功能(静态方法)的访问。

例如,输入库可能具有:

class KeyEvent
{
    public:
      static const int KEY_DOWN = 111;
      static const int KEY_UP = 112;
      ...
}

//And then in your code
#include <KeyEvent>

void poolEvent(Key *key)
{
    if(key->type() == KeyEvent::KEY_DOWN)
      ...
}
于 2015-02-11T19:08:56.427 回答
1

我目前不熟悉静态的 c++ 语法。但在 c++-cli (.net, Visual C++) 中::是正确的。
出于静态的目的:
在许多情况下使用它们是有意义的。通常,当您想要存储属于类本身(意味着类的所有对象)而不是单个对象/实例的信息时。

于 2015-02-11T18:49:42.497 回答
0

它类似于全局变量,只是它不是在全局命名空间中定义的。

您可以在引入命名空间之前编写的 C++ 代码中找到它,或者在模板元编程中发现它更有用。

一般来说,我不建议在您的示例中使用它,而是希望尽可能避免全局状态。否则,您最终会得到难以测试的代码。

于 2015-02-11T18:47:35.747 回答