【问题标题】:Can we declare a friend function with no argument?我们可以声明一个不带参数的友元函数吗?
【发布时间】:2013-07-30 08:22:40
【问题描述】:

有可能吗?

class sample {
        private:
           int x;
        public:
           friend void fun();
};

friend 没有参数的函数!

我认为不可能

因为友元函数不是类的“成员” 所以我们不能用类对象调用

喜欢:

sample s;
s.fun();

【问题讨论】:

  • @sehe:为什么?还有墨守成规的朋友。
  • @P0W “这有意义吗”是什么意思?
  • @MarkGarcia 我的意思是为什么要创建类对象然后以这种方式访问​​私有成员。

标签: c++ class friend-function


【解决方案1】:

是的,您可以:

void fun()
{
  sample s;
  s.x++;   // OK, fun() is a friend of sample
}

sample globalSample; // yikes, a global variable

void fun()
{
  int i = globalSample.x; // OK, fun() is a friend of sample
}

【讨论】:

    【解决方案2】:

    是的,你可以。这可能有很多原因,例如访问私有静态成员或可能存在sample 的全局实例。 fun 也有可能创建一个 sample 的实例并获取其私有信息。

    函数创建实例和使用它的工作示例:

    #include <iostream>
    class sample {
        private:
           int x;
        public:
           friend void fun();
    };
    
    void fun()
    {
        sample s;
        s.x = 555555555;
        std::cout << s.x;
    }
    int main(){
        fun();
        return 0;
    }
    

    全局实例示例:

    #include <iostream>
    #include <string>
    class sample {
        private:
           int x;
        public:
           friend void fun();
    };
    sample s;
    
    void fun()
    {
    
        s.x = 555555555;
        std::cout << s.x;
    }
    int main(){
        fun();
        return 0;
    }
    

    私有静态成员示例:

    #include <iostream>
    #include <string>
    class sample {
        private:
           int x;
           static const int w = 55;
        public:
           friend void fun();
    };
    
    
    void fun()
    {
    
        std::cout << sample::w;
    }
    int main(){
        fun();
        return 0;
    }
    

    【讨论】:

    • 请举个例子?
    • @DixitSingla 添加示例
    【解决方案3】:

    您当然可以.. 参见此处查看示例code。但是要定义内联函数,您需要将sample 作为参数,否则ADL 将不起作用并且编译器将无法解析func。参见示例here

    【讨论】:

    • 感谢 Asha 抽出宝贵时间请告诉我一件事,我们可以在类中定义朋友函数吗?如果没有,那为什么不呢?
    • @juanchopanza:在这种特殊情况下,这似乎是不可能的。当不接受任何参数时,编译器将无法找到fun。见这里:codepad.org/6aaNmHK6
    • @DixitSingla:更新答案。
    • @Asha 困惑为什么编译器在不接受任何参数的情况下无法找到乐趣?请详细说明?
    • @DixitSingla:这是因为参数依赖查找在 C++ 中的工作方式。看看这个问题了解更多细节:stackoverflow.com/questions/7785886/…
    【解决方案4】:

    可以有没有参数的友元函数。您需要另一种访问类样本对象的方法。别忘了,友元函数也允许你访问类样本的私有静态变量,以备不时之需

    【讨论】:

      【解决方案5】:

      是的,但是对于变量,您需要它们是全局的。在您的情况下,sample 类型的全局对象。或者可能在fun() 的定义中在函数内部创建对象

      sample globalObject;
      
      void fun()
      {
       globalObject.x++;   //this will work as fun() is friend function of sample.
      }
      

      【讨论】:

        【解决方案6】:

        可能有一个不带参数的友元函数。很少用。

        【讨论】:

        • 你能举个例子解释一下吗?
        • 您可以将其用作辅助函数。一种情况可能是在对象状态发生变化时传达一些信息,您可以调用将显示一些文本的朋友函数。
        【解决方案7】:

        当然可以。您似乎想知道为什么要这样做。例如,它可以访问静态私有成员变量。或者它可以通过某种方式访问​​它获得的对象的私有成员(单例、全局(容器)对象、...)

        【讨论】:

          【解决方案8】:
          sample s;
          s.fun();
          

          这无论如何都行不通,因为 C++ 中的“友谊”只是解除了对私有/受保护成员的访问限制。朋友不是班级成员,因此您无法调用 s.fun()。

          但是,您可以像您描述的那样声明一个友元函数,并且您可以通过该函数访问示例类的私有成员。

          【讨论】:

            【解决方案9】:

            友元方法可能很有用,因为这种访问私有/受保护数据的成员仅限于指定的那些方法。这个方法是否有参数或返回类型并不重要。

            template <class T>
            class CLinkedListNode {
            public:
                CLinkedListNode(CLinkedList<T>* Parent) : _Parent(Parent) {
                }
            protected:
                CLinkedListNode * _Next;
                T _Data;
                CLinkedList<T>* _Parent;
            
                friend CLinkedListNode<T>* CLinkedList<T>::find(); // Only CLinkedList<T>::find() may access data members
                friend void sort(); // All sort methods may access data members
            };
            

            因此想象有一个类 CLinkedList,其 find() 方法能够访问 CLinkedListNode 的所有数据成员。

            template <class T>
            class CLinkedList {
            // ...
                CLinkedListNode<T>* find() {
                    CLinkedListNode<T>* Node = new CLinkedListNode<T>(this);
                    CLinkedListNode<T>* Find = Node->_Next;
                    while (Find->_Next) {
                        // Do something
                        Find = Find->_Next;
                    }
                    // ...
                    return Node;
                }
            };
            

            【讨论】:

              猜你喜欢
              • 2023-01-24
              • 2020-08-04
              • 2016-02-29
              • 2011-10-06
              • 1970-01-01
              • 1970-01-01
              • 2022-01-09
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多