2

我想知道类对象有什么样的类成员访问friend函数和static成员函数。具体来说,有什么区别以及为什么要使用另一种。据我了解,声明为friend类或static成员的函数都可以访问该类的任何实例的私有成员。

我将举一个简单的例子来说明为什么它们看起来与我如此相似。这两个功能似乎都具有相同的访问权限,operator<并且MyClass::lessThan可以做完全相同的事情。

class MyClass {
    friend bool operator<(const MyClass &left, const MyClass &right);
public:
    MyClass(int pub, int priv) : m_pub(pub), m_priv(priv) {}
    static bool lessThan(const MyClass &left, const MyClass &right);
    int m_pub;
private:
    int m_priv;
};

bool operator<(const MyClass &left, const MyClass &right) {
    return ( (left.m_pub < right.m_pub) && (left.m_priv < right.m_priv) );
}

bool MyClass::lessThan(const MyClass &left, const MyClass &right) {
    return ( (left.m_pub < right.m_pub) && (left.m_priv < right.m_priv) );
}

int main(int argc, const char* argv[]) {
    MyClass a(1, 2),
        b(3, 4),
        c(-1, 1);
    cout << "a < b        = " << (a<b) << endl;
    cout << "a lessThan b = " << MyClass::lessThan(a,b) << endl;
    cout << "a < c        = " << (a<c) << endl;
    cout << "a lessThan c = " << MyClass::lessThan(a,c) << endl;
}

显然这是一个简化的例子,但我想我的问题分为两部分:

  1. 在成员访问方面,朋友和静态函数有什么区别?
  2. 在决定使用哪一种时应该考虑哪些事情?
4

5 回答 5

2

请记住,虽然友元函数的原型出现在类定义中,但友元函数不是函数成员。类的元函数是在类之外定义的,但元函数可以访问非公共成员。有些人认为“友谊”会破坏信息隐藏。有时友元函数用于创建测试器类。

当一个对象类应该只共享一个变量的一个副本时,使用静态数据成员。因此,当所有类成员仅一份副本就足够时,您必须使用静态数据成员来节省存储空间。

对于静态成员函数,您可以查看以下内容:何时使用静态成员函数?

于 2012-09-12T00:12:26.553 回答
1

它们是不同的概念:

如果一个类、方法或函数是类 X 的朋友,则该类、函数或方法可以访问类 X 的成员,这些成员被声明为私有,因此通常无法在类外部访问

class A{
  private:
     int x;
  friend void foo(A& a);

};

void foo(A& a){
    a.x = 3; //Access okay, foo is a friend of A
} 

void bar(A& a){
   a.x = -1; // Compiler will complain A::x is private
}

静态成员要么是该类的所有对象实例之间共享的数据成员,要么是可以在没有该类的实例对象的情况下调用的方法。

class B{

  private:
    static int y;

  public:
    static void printY();
    void alterY();

}

int B::y=3;

void B::printY(){
   cout<<y;
}

void B::alterY(){
   y++;
   cout<<y;
}


B b1,b2;
B::printY();// will output 3
b1.alterY();// will output 4
b2.alterY();// will output 5
于 2012-09-12T00:04:04.540 回答
1

静态方法可以在不通过类实例的情况下调用,因此它们没有任何直接访问权限,它们类似于全局函数,但嵌套在类的命名空间中。但是,如果您给他们一个该类的实例作为参数,他们将能够访问成员变量,而无需像非静态方法一样通过访问器。像静态方法一样,友元函数如果你给他们一个他们是友元的类的实例作为参数,他们将能够直接访问成员变量。

于 2012-09-12T00:04:35.993 回答
1
  1. 他们都可以访问班级的所有成员,包括私人成员
  2. 您需要确定一个函数在逻辑上是否属于需要访问其成员的类,或者它是否属于另一个类或根本不属于任何类。在第一种情况下(逻辑上属于类的函数)使函数静态;在第二种情况下,使其成为朋友,并根据您的设计将其添加到逻辑所属的类或命名空间中。
于 2012-09-12T00:04:49.267 回答
0

在成员访问方面,朋友和静态函数有什么区别?

没有任何。他们都有完全的访问权限。

在决定使用哪一种时应该考虑哪些事情?

它完全取决于上下文以及使代码更易于阅读的原因。

在您上面的示例中,我肯定会更喜欢它bool operator<()MyClass::lessThan()因为它使代码更易于阅读。

于 2012-09-12T00:24:56.313 回答