我理解使用静态成员函数的一个好处是不必初始化类来使用它们。在我看来,他们的另一个好处可能是没有直接访问该类的非静态内容。
例如,通常的做法是,如果您知道函数将具有不可更改的参数,则只需标记这些常量。 e.g:
bool My_Class::do_stuff(const int not_to_be_changed_1,
std::vector<int> const * const not_to_be_changed_2)
{
//I can't change my int var, my vector pointer, or the ints inside it.
}
因此,使用静态成员函数来限制访问是有效的。例如,假设您有一个功能
void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
那么我们不会访问该类的任何成员变量。所以,如果我将功能更改为:
static void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
我现在得到一个错误,如果我无意中试图访问我的一个私有var等等(除非我自己传递一个我的类的实例,这将是有目的的^ _ ^!)
这是一种有效的技术,类似于主动制作不应该改变常数的args吗?
在效率或使用方面可能有哪些缺点?
我要问的主要原因是我读过的大多数“静态”教程没有提到以这种方式使用它,所以我想知道是否有一个很好的理由为什么不这样做,因为它看起来像是一个有用的工具
编辑1 :这种用法的进一步合理理由:
我有一个函数print_error,如上所述。我可以使用命名空间:
namespace MY_SPACE {
static void print_error(...) {
...
}
class My_Class {
....
void a(void)
}
}
但这是一种痛苦,因为我现在必须延长所有的var声明,即
MY_SPACE::My_Class class_1;
所有从我的班级中移除一个函数,基本上 是我班级的成员。
当然,对功能有多种级别的访问控制:
//can't change pointer to list directly
void My_Class::print_error(std::vector<int> const * error_code_list) {...}
//can't change pointer to list or list members directly
void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//non-const member vars/functions
void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
//can't change pointer to list or list members directly, access
//non-static member vars/functions
static void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//member vars/functions that are not BOTH static and const
static void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
当然这有点不典型,但减少程度所以使用const函数和const变量。我已经看过许多人可以使用const函数的例子,但没有。然而有些人认为这是一个好主意。我知道许多初学c ++程序员不了解const函数或静态函数的含义。同样,很多人都会理解。
那么为什么有些人如此坚决地反对使用它作为访问控制机制,如果语言/规范允许这样使用它,就像使用const函数一样呢?
答案 0 :(得分:5)
任何成员函数都应该有权访问该对象的其他成员。你为什么试图保护自己?
静态成员通常会谨慎使用,例如工厂方法。您将创建一个使下一个人使用您的代码的情况变为“WTF ???”
答案 1 :(得分:3)
不要这样做。使用static
作为访问控制机制是一种野蛮的憎恶。
不这样做的一个原因是因为它很奇怪。维护程序员很难理解你的代码,因为它太奇怪了。可维护的代码是很好的代码。每个人都获得const
种方法。没有人得到static-as-const
。代码的最佳文档是代码本身。自我记录代码是您应该追求的目标。不是这样你不必写评论,但是他们不必读他们。因为你知道他们不会反正。
不这样做的另一个原因是因为你永远不知道未来会带来什么。您上面的print_error
方法现在不需要访问类的状态。但我可以看到有朝一日可能需要它。假设您的类是UDP套接字的包装器。在会话中间的某个时间,另一端猛击门。你想知道为什么。您发送或接收的最后一条消息可能存在线索。你不应该抛弃它吗?你需要国家。
这样做的错误原因是它提供了成员访问控制。是的,这样做,但已有机制。假设您正在编写一个您希望确保不会更改对象状态的函数。例如,print_error
不应更改任何对象的状态。所以制作方法const
:
class MyClass
{
public:
void print_error(const unsigned int error_no) const;
};
...
void MyClass::print_error(const unsigned int error_no) const
{
// do stuff
}
print_error
是const
方法,有效地表示this
指针为const
。您无法更改任何非mutable
成员,也无法调用任何非const
方法。这不是你想要的吗?
答案 2 :(得分:1)
毫无疑问,全局范围函数,静态成员函数和友元函数彼此之间并不完全正交。在某种程度上,这很大程度上是因为它们旨在与程序员有一些不同的语义含义,即使它们产生类似的输出。
特别是,静态成员方法和友元函数之间的唯一区别是名称空间不同,静态成员的名称空间为::className::methodName
,而友元函数只是::friendFunctionName
。它们都以相同的方式运作。
嗯,实际上还有另外一个区别,静态方法可以通过指针间接访问,这在多态类的情况下很有用。
所以问题是,该函数是否属于该类的“ part ”?如果是这样,请使用静态方法。如果没有,请将该方法放在全局范围内,如果它可能需要访问私有成员变量,则使其成为朋友(或者如果不需要,则将其设置为朋友)
答案 3 :(得分:1)
当静态成员函数与类相关但不对该类的实例进行操作时,应使用它们。
示例包括一类实用程序方法,所有这些方法都是静态的,因为您从不需要实用程序类本身的实际实例。
另一个例子是使用静态辅助函数的类,这些函数对于类外的其他函数足够有用。