使用“静态”关键字限制C ++成员函数中的访问

时间:2010-10-05 19:15:10

标签: c++ class function static scope

我理解使用静态成员函数的一个好处是不必初始化类来使用它们。在我看来,他们的另一个好处可能是没有直接访问该类的非静态内容。

例如,通常的做法是,如果您知道函数将具有不可更改的参数,则只需标记这些常量。 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函数一样呢?

4 个答案:

答案 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_errorconst方法,有效地表示this指针为const。您无法更改任何非mutable成员,也无法调用任何非const方法。这不是你想要的吗?

答案 2 :(得分:1)

毫无疑问,全局范围函数,静态成员函数和友元函数彼此之间并不完全正交。在某种程度上,这很大程度上是因为它们旨在与程序员有一些不同的语义含义,即使它们产生类似的输出。

特别是,静态成员方法和友元函数之间的唯一区别是名称空间不同,静态成员的名称空间为::className::methodName,而友元函数只是::friendFunctionName。它们都以相同的方式运作。

嗯,实际上还有另外一个区别,静态方法可以通过指针间接访问,这在多态类的情况下很有用。

所以问题是,该函数是否属于该类的“ part ”?如果是这样,请使用静态方法。如果没有,请将该方法放在全局范围内,如果它可能需要访问私有成员变量,则使其成为朋友(或者如果不需要,则将其设置为朋友)

答案 3 :(得分:1)

当静态成员函数与类相关但不对该类的实例进行操作时,应使用它们。

示例包括一类实用程序方法,所有这些方法都是静态的,因为您从不需要实用程序类本身的实际实例。

另一个例子是使用静态辅助函数的类,这些函数对于类外的其他函数足够有用。