当前位置:首页 > 编程笔记 > 正文
已解决

【C++】从入门到精通第三弹——友元函数与静态类成员

来自网友在路上 184884提问 提问时间:2023-11-08 14:53:26阅读次数: 84

最佳答案 问答题库848位专家为你答疑解惑

这里写目录标题

  • 静态类成员
  • 友元
  • 友元方法

静态类成员

类成员一般都需要通过对象来访问,不可以通过类名直接访问,但是当我们将类成员定义为静态类成员,则允许使用类名直接访问。
静态类成员是在类成员前定义static关键字。

  1 #include<iostream>2 using namespace std;3 class Cbook4 {5     public:6        static int price;7 };8 int Cbook::price = 410;9 int main()10 {11     Cbook cbook;12     cout<<"Cbook in"<<Cbook::price<<endl; //通过类名直接访问类成员13     cout<<"Cbook use"<<cbook.price<<endl;//通过对象访问静态类成员14 15 16     return 0;17 }

注意:在定义静态类成员时,通常需要在类体外部对静态类成员进行初始化。
静态类成员是被所有的类共享的,无论定义多少个类对象。类的静态类成员只有一份,同时,如果一个对象修改了静态类成员,那么其他对象的静态类成员也将改变(修改的是同一个静态类成员)

静态类成员可以是当前类的类型,其他数据类成员只能是当前类的指针或应用类型,在定义类成员时,对于静态类成员,其类型可以是当前类的类型,而非静态类·成员则不可以,除非数据成员的类型为当前类的指针或引用类型。

  8 class CBOOK9 {10     public:11         static int price;12     //    CBOOK cbook;错误,非法定义13         static CBOOK cook;14         CBOOK *cbook;15 };

静态类成员可以作为成员函数的默认参数,在定义类的成员函数时,可以为成员函数指定默认参数,其参数的默认值也可以是类的静态类成员,但是不同的数据成员不能作为成员函数的默认参数。

类的静态成员函数只能访问类的静态成员,而不能访问普通的数据成员。
而且静态类成员函数不能定义为const成员函数,如果函数的实现代码位于类体之外,则在函数的实现部分不能再标识static关键字。

友元

友元概述
友元是使用friend关键字, 让特定的函数或者别的类的所有成员函数对私有数据成员进行读写。
好处是:可以保持数据的私有性,又可以让特定的类或者函数直接访问私有成员。
为了提升效率,友元可以让普通函数直接访问一个类的保护或私有数据成员,但是如果没有友元机制,就只能将类的数据成员声明为公共的,从而任何函数都可以无约束地访问它。
友元函数:

1 #include<iostream>2 using namespace std;3 class Friendfunction4 {   5     public:6         Friendfunction()7         {8             m_height = 0;9             m_width = 0;10         }11         Friendfunction(int height,int width)12         {13          m_width = width;14          m_height = height;15         }16         int getHeight()17         {18             return m_height;19         }20         int getWidth()21         {22             return m_width;23         }24         friend int friendfunction(Friendfunction &myret);25         protected:26         int m_height;27         int m_width;28 };29 int friendfunction(Friendfunction &myret)30 {31     return myret.m_height*myret.m_width;32 }33 int main()34 {35     Friendfunction ff(120,210);36     cout<<"result = "<<friendfunction(ff)<<endl;37 38     return 0;39 }

在函数friendfunction中可以直接使用Friendfunction类对象中的数据成员,就是因为第24行代码的作用:

 24         friend int friendfunction(Friendfunction &myret);

此例子既很好的保护隐藏了数据,又可以使外界的特定函数直接访问这些隐藏数据。

接下来介绍友元类
就如下面第14行代码所示 : friend class Clist; 就可以声明友元类啦。用法和功能与友元函数用法功能类似。这里就不再详细赘述了,直接看代码:

  1 #include<iostream>2 #include<string>3 using namespace std;4 class Cltem5 {6     private:7         string m_name;8         void outputname()9         {10             cout<<"name = "<<m_name<<endl;11             12         }13     public:14        friend class Clist;15         void setltemname(string name)16         {17            m_name= name;18         }  19 };      20 class Clist21 {22     private:23         Cltem m_ltem;24     public:25         void outoutltem();26 };27 void Clist::outoutltem()28 {29     m_ltem.setltemname("beijing");30     m_ltem.outputname();31 }32 int main()33 {34     Clist list;35     list.outoutltem();36 37     return 0;38 }

定义Cltem类时,使用了friend关键字将Clist类定义为Cltem类 的友元,这样一来,Clist类中的所有方法都可以访问Cltem类中的私有成员了。

友元方法

在我们真正开发程序时,有时候需要控制一个类对当前类的私有成员的发法。比如,我们需要实现只允许Cbook类中的某个成员来访问·Clibrary类的私有成员,而不允许其他成员函数访问Clibrary类的私有数据,这可以通过定义友元函数来实现。在定义Clibrary类的时候,可以将Cbook类的某个方法定义为友元方法,这样就限制了只有该方法允许访问Clibrary类的私有成员。

1 #include<iostream>2 using namespace std;3 class Clibrary;4 class Cbook5 {6     public:7         Cbook();8         ~Cbook();9         Clibrary *position;10         void putcbook(); //声明友元11         //void notfriendcbook();//不声明友元,作为对比12 };13 class Clibrary14 {15     friend void Cbook::putcbook();16     private:17     string name;18     void putname()19     {20         cout<<"name = "<<name<<endl;21     }22     public:23     void setname(string name);24 };25 void Clibrary::setname(string name)
26 {   27     this->name = name;28 }29 void Cbook::putcbook()30 {   31     position->setname("beijing");32     position->putname();33 }  /*34 void Cbook::notfriendcbook()35 {36     position->setname("beijing");37     position->putname();38 }*/39 Cbook::Cbook()40 {41     position = new Clibrary();42 }43 Cbook::~Cbook()44 {45     delete position;46    position = NULL;47 }48 49 int main()50 {51     Cbook cook;52     cook.putcbook();53 54    // cook.notfriendcbook();55     return 0;56 }

就像上面代码所示,如果把没有声明友元的成员函数放开,就会出现下面这样的错误。

[bsk@localhost c++]$ g++ friendmethod.cpp 
friendmethod.cpp: In member function ‘void Cbook::notfriendcbook()’:
friendmethod.cpp:18:10: error: ‘void Clibrary::putname()’ is privatevoid putname()^
friendmethod.cpp:37:23: error: within this contextposition->putname();

原因也很简单,就是因为notfriendcbook()成员函数不是Clibrary类的友元,所以这个成员函数就不能访问去访问Clibrary类中的私有属性。
此外,全局函数也可以作为类友元,一样可以访问类中的私有成员。

最后简单来谈一下
友元函数在访问类对象中的成员时,不需要通过对象名。友元函数没有this指针,如果不通过对象名就无法找到类对象中的非static成员,也就无法访问。但是当访问类对象中的static成员时,就可以不用通过对象名访问。

查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"【C++】从入门到精通第三弹——友元函数与静态类成员":http://eshow365.cn/6-35422-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!