C++ 类静态成员(static)、类常量成员(const)、friend友元
发布日期:2021-05-07 15:11:16 浏览次数:18 分类:精选文章

本文共 3813 字,大约阅读时间需要 12 分钟。

原文链接:

一、类静态成员(static)

什么是静态变量、静态函数

  • 在介绍类静态成员之前,先介绍一下静态变量、静态函数

 

  • 静态局部变量存在域(全局数据区),作用域(块作用域)
  • 静态全局变量存在域(全局数据区),作用域(整个文件)
  • 静态函数:存在域(全局数据区),作用域(整个文件)
static int a=10;//全局静态变量static void add();//静态函数int main(){    {        static int b=10;//局部静态变量    }}

特点:

  • 静态static修饰的变量、函数,只需要初始化一次,下次再执行到static修饰的相同代码时,自动跳过。
  • 静态static修饰的变量、函数,从程序开始执行时生效,且只在当前文件(.c/cpp)有效(链接属性),其他文件不可用

静态数据成员特点

 

  • 静态成员不属于某一个对象,而是属于整个类(定义在数据段)
  • 静态成员供所有对象共享,每个对象可以调用且修改。一个对象修改,其他对象也跟着变化
  • static成员变量可以在类型声明并初始化。但是建议在类内定义、类外初始化
  • 可以直接通过类名直接访问
class Cperson{private:    static int age;    static int getAge();}//类外初始化int Cperson::age=18;int Cperson::getAge(){    return age;}int main(){    Cperson person1;    person.age=20;//调用并改变静态成员        //直接通过类名就可调用    cout<

 

类静态函数

  • 因为静态函数不属于某一对象,所以函数内不存在this指针
  • 静态成员函数不能被声明为const类型(“静态成员函数是属于类的,而不是某个具体对象,在没有具体对象的时候静态成员就已经存在,静态成员函数不会访问到非静态成员,也不存在this指针。而成员函数的const就是修饰this指针的,既然静态成员函数不会被传递this指针,那const自然就没有必要了”)
  • 静态函数内部只能访问静态成员(变量、函数),不能访问普通成员。原因:静态函数在类定义时就已经开辟内存空间,而普通成员只有当定义对象时开会开辟内存空间,所以调用普通成员会出错
  • 普通函数内部可以调用静态成员,也可以调用普通成员。原因:同上,普通函数调用时开辟内存空间,所有都可调用
class Cperson{private:    float height;    static int age;    static void setPerson();}int Cperson::age=18;void Cperson::setPerson(){    age=20;//正确,可调用静态成员    height=178;//错误,不可调用普通成员}

 

二、类常量成员(const)

const数据成员

 

  • const数据成员只能在构造函数的初始化列表进行初始化
  • const数据成员在初始化之后,不允许再次修改值
class Cperson{private:    const int age;//常量数据成员    float height;public:    Cperson(int age,float height);}; Cperson::Cperson(int age,float height):age(age){    this->height=height;}

 

const函数成员

 

  • const函数成员的目的:函数内不准对类的成员数据进行更改(对成员数据只读)
  • 可以改变函数的非const参数、以及函数内部的局部变量
  • const成员函数不可调用非const函数成员(本质:防止修改非const函数内的值)

优点

  • 能通过const语法防止我们对自身类的数据进行误操作
  • 当对象为常量对象时,只允许访问类的常量函数成员
class Cperson{private:    const int age;//常量数据成员    float height;public:    int getAge()const;    void setHeight(float height);};int Cperson::getAge()const{    //age++;//错误做法,不准对成员变量进行修改    return age;}void Cperson::setHeight(float height){    this->height=height;} int main(){    Cperson person1;    person1.getAge();//正确    person1.setHeight(175.5);//正确     const Cperson person1;    //person1.setHeight(175.5);错误,const对象不能调用非const函数    person1.getAge();//正确}

 

基于const函数的重载

  • const函数的重载,调用的时候,系统根据定义的类对象类型来调用对应的函数

calss Person{    int age;public:    Person& setAge(int age);//一    const Person& setAge(int age)const;//二};int main(){    Person p1;    const Person p2;    p1.setAge(18);//调用第一个    p2.setAge(20);//调用第二个}

 

友元(friend)

1.概念:

  • 通过友元,打破了类的封装性,可以访问类内的所有成员

2.分类:

  • 友元函数、友元类

友元函数

  • 概念友元函数是一个普通函数,不属于类,但需要在类内表明友元关系
  • 友元函数可访问类内所有成员,但类不可以访问友元函数内部数据

 

格式:

  • 友元函数可以在类内声明时,需要加上关键字friend
  • 友元函数可以在类外声明,类外定义。需要加上关键字friend
class Cperson{private:    int age;public:    friend void setPersonAge(Cperson& p,int age);}; void setPersonAge(Cperson& p,int age) //函数在类外声明和定义{    p.age=age;} int main(){    Cperson person;    setPersonAge(person,18);}
class Cperson{private:    int age;public:    friend void setPersonAge(Cperson& p,int age)//友元函数在类内定义    {        p.age=age;    }}; void setPersonAge(Cperson& p,int age); int main(){    Cperson person;    setPersonAge(person,18);}

友元类

  • 友元类也不属于类成员,不拥有this指针
  • 一个类成为另一个类的友元类时,就可以访问另一个类的所有成员

 

友元类的形式分为两种:

  • 使整个类成为友元
  • 使类中的某一部分函数成为友元
  • 使整个类成为友元:
class Cb;//声明类class Ca{private:    int num;public:    friend class Cb; //使整个类成为Ca的友元,则Cb所有的成员都可以访问Ca的所有成员}; class Cb{public:    void setCaNum(Ca& a);    void Func();};

 

  • 使类中的某一部分函数成为友元:
class Cb;//声明类class Ca{private:    int num;public:    friend void Cb::setCaNum(Ca& a);//只有Cb的setCaNum成为Ca的友元}; class Cb{public:    void setCaNum(Ca& a);    void Func();}

 

友元特点

  • 单方向性:即友元可访问类,但是类不能访问友元
  • 不传递性A是B的友元,C是A的友元,但C不是B的友元
  • 不继承在上面的友元类中有介绍

友元的声明和作用域的关系

  • 使用一个友元时,要考虑到其友元的声明和作用域的问题,请看下面代码
class X{public:    friend void f(){} //友元函数在类内定义     X() {f();}   //错误,f()函数在下面才声明,此处检测不到    void g();    void h();}; void X::g(){ return f(); }//错误,此时f()函数还没有被声明 void f(); //声明函数 void X::h(){ return f(); } //正确,检测到f()函数被声明

 

上一篇:C++ 一致性初始化、初值列(initializer_list)及成员变量初始化方式
下一篇:C++ 构造函数、析构函数、拷贝构造函数

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月02日 18时33分55秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章