Why/When 我想使用 class 数据成员而不定义 class 的对象吗?
Why/When would I want to use a class data member without defining an object of the class?
在 C++ 中可以使用 class 的数据成员而无需定义 class 的对象,方法是在 public 部分中将该数据成员定义为 static
变量,如下面的代码示例所示。问题是,why/when 我想这样做吗?我该怎么做?
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();
}
它类似于全局变量,只是它不在全局命名空间中定义。
您可以在引入命名空间之前编写的 C++ 代码中找到它,或者在模板元编程中找到它更有用。
一般来说,我不建议像您的示例那样使用它,而是希望尽可能避免使用全局状态。否则,您最终会得到难以测试的代码。
将 class 成员变量声明为 static
本质上使它成为一个单例对象,由 class 的所有实例共享。这对于计数器、信号量和锁以及需要由其他 class 成员共享的其他类型的数据非常有用。
声明它 public
可以让 class 的所有用户都可以访问它。不过,允许 class 变量可由 class 之外的函数修改通常不是一个好主意。
另一方面,声明它 const
是为 class.
提供公开可读常量的常用方法
例子
您的图书馆 class:
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
是class 的静态常量,在本例中它告知外界class 中包含的代码版本。它通过语法 Foo::VERSION
.
访问
另一方面,静态counter
变量是class私有的,因此只有Foo
的成员函数可以访问它。在这种情况下,它被用作活动 Foo
对象数量的计数器。
我目前不熟悉静态的 c++ 语法。但在 c++-cli(.net、Visual C++)中 ::
是正确的。
出于静力学的目的:
在许多情况下使用它们是有意义的。通常,当您想要存储属于 class 本身的信息(意味着属于 class 的所有对象)而不是属于单个 object/instance 的信息时。
尽管最初并非为此目的而发明,structs
的 static
constexpr
数据成员是模板 meta-programming 的 backbone。只需查看 limits
标准库 header 作为一个简单示例。
例如,我们可以定义一个围绕内置 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
如前所述,静态成员变量作为 'global' 变量工作,但在 class 命名空间内。
所以对于计数器或者对象间的共享资源很有用。
在 '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)
...
}
在 C++ 中可以使用 class 的数据成员而无需定义 class 的对象,方法是在 public 部分中将该数据成员定义为 static
变量,如下面的代码示例所示。问题是,why/when 我想这样做吗?我该怎么做?
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();
}
它类似于全局变量,只是它不在全局命名空间中定义。
您可以在引入命名空间之前编写的 C++ 代码中找到它,或者在模板元编程中找到它更有用。
一般来说,我不建议像您的示例那样使用它,而是希望尽可能避免使用全局状态。否则,您最终会得到难以测试的代码。
将 class 成员变量声明为 static
本质上使它成为一个单例对象,由 class 的所有实例共享。这对于计数器、信号量和锁以及需要由其他 class 成员共享的其他类型的数据非常有用。
声明它 public
可以让 class 的所有用户都可以访问它。不过,允许 class 变量可由 class 之外的函数修改通常不是一个好主意。
另一方面,声明它 const
是为 class.
例子
您的图书馆 class:
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
是class 的静态常量,在本例中它告知外界class 中包含的代码版本。它通过语法 Foo::VERSION
.
另一方面,静态counter
变量是class私有的,因此只有Foo
的成员函数可以访问它。在这种情况下,它被用作活动 Foo
对象数量的计数器。
我目前不熟悉静态的 c++ 语法。但在 c++-cli(.net、Visual C++)中 ::
是正确的。
出于静力学的目的:
在许多情况下使用它们是有意义的。通常,当您想要存储属于 class 本身的信息(意味着属于 class 的所有对象)而不是属于单个 object/instance 的信息时。
尽管最初并非为此目的而发明,structs
的 static
constexpr
数据成员是模板 meta-programming 的 backbone。只需查看 limits
标准库 header 作为一个简单示例。
例如,我们可以定义一个围绕内置 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
如前所述,静态成员变量作为 'global' 变量工作,但在 class 命名空间内。 所以对于计数器或者对象间的共享资源很有用。
在 '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)
...
}