C++类的拓展

1、类成员存储(class member storage)

对于类的大小,发现成员函数并不用类的存储空间。 只用一段空间来存放这个共同的函数代码段,在调用各对象的函数时,都去调用这个公用的函数代码。 所有的对象都调用共用的函数代码段,如何保证访问的是调用对象的成员呢?为此,C++设置了 this 指针,对象在调用公用函数时,并将对象的指针作为隐含参数传入其内,从而保证了访问的成员,属于调用者。

2、const 修饰类

const修饰数据成员

const 修饰数据成员,称为常数据成员,可能被普通成员函数和常成员函数来使用,不可以更改。必须初始化,可以在类中,也就是在类中定义这个变量的同事初始化(不推荐),或初始化参数列表中(这是在类对象生成之前唯一一次改变 const 成员的值的机会了)。 不可以在构造器中初始化,只能是初始化参数列表中初始化。否则报错

const修饰成员函数

const修饰成员函数承诺在本函数内部不会修改类内的数据成员,为此,也只能调用承诺不会改变成员的其它 const 成员函数,而不能调用其它非 const 成员函数。

const 修饰函数放在,声明之后,实现体之前,大概也没有别的地方可以放了。

void dis() const
{
    
}

const修饰成员函数注意要点

const 修饰函数,在声明之后,实现体之前。

const 函数只能调用 const 函数。非 const 函数可以调用 const 函数。

如果 const 构成函数重载,const 对象只能调用 const 函数,非 const 对象优先调用非 const 函数。

类体外定义的 const 成员函数,在定义和声明处都需要 const 修饰符(有些关键字是定义型的,有些是声明型的)。

3、static 修饰类

C++扩展了 static 在类中的语意,用于实现在同一个类,多个对象间数据共享,协调行为的目的。静态变量有全局变量的优势,又不会像全变量一样被滥用。而这一类变量,即可以通过类来管理,也可以通过类的静态函数来管理。类的静态成员,属于类,也属于对象,但终归属于类。

static修饰数据成员

static修饰的数据成员声明在类内部,然后要在类外部初始化,既可以通过对象也可以通类访问(类访问也得是public才能访问)。static 成员使用时必须初始化,且只能类外初始化。声明与实现分离时,只能初始化在实现部分(cpp 部分)。注意这个static这个关键字只能放在类的声明处,也就是类里边,在外部初始化的时候不要写这个关键字。就像下面的代码一样:

#include <iostream>
using namespace std;
class A
{
public:
    void foo()
    {
        cout<<"void foo"<<endl;
        share++;
    } 
private:
    static int share; //static修饰数据成员
};

int A::share = 0;  //类外实现初始化,如果类分为.h和.cpp.这行代码写到.cpp中

static修饰的数据成员可以在所有的对象中共享数据,比如一个对象改了static修饰的数据成员变量,那么别的对象访问的时候也就是前一个对象修改了的数据

static 修饰成员函数

为了管理静态成员,C++提供了静态函数,以对外提供接口。并且静态函数只能访问静态成员。不能调用其他成员,包括成员函数和其他的非static数据成员。

在类内部函数的声明和定义,就按照下面的方法实现

static int fooInvokeCount() //只能访问静态成员,不能访问别的数据成员
{
    
}

静态成员函数只能访问静态数据成员。原因:非静态成员函数,在调用时 this指针时被当作参数传进。而静态成员函数属于类,而不属于对象,没有 this 指针。

4、static const 类型

如果一个类的成员,既要实现共享,又要实现不可改变,那就用 static const 组合模式来修饰。修饰成员函数,格式并无二异,修饰数据成员,必须要类内部初始化。

5、指向类成员的指针

C++扩展了指针在类中的使用,使其可以指向类成员(数据成员和函数成员),这种行为是类层面的,而不是对象层面的。

指向类数据成员的指针

指向类数据成员的指针其实并没有多大的意义,因为数据成员一般都是private的,只有类的数据成员是public的时候才有意义。不过我们也来说说。

声明

<数据类型><类名>::*<指针名>

初始化

<数据类型><类名>::*<指针名>=& <类名>::<非静态数据成员>

解引用

<类对象名>.*<指向非静态数据成员的指针>

<类对象指针>->*<指向非静态数据成员的指针>

实例:

#include <iostream>
using namespace std;
class Student
{
public:
    Student(string n, int nu):name(n),num(nu){}
    string name;
    int num;
};
int main()
{
    Student s("zhangsan",23);
    
    string Student::*pn = &Student::name; //指向类数据成员的指针  就这么定义
    cout<<s.*pn<<endl;                      //解引用
    
    Student *ps = new Student("zhaoliu",35); 
    cout<<ps->*pn<<endl;
    return 0;                                //解引用
}

指向类成员函数的指针

定义一个指向非静态成员函数的指针必须在三个方面与其指向的成员函数保持一致:参数列表要相同、返回类型要相同、所属的类型(类名)要相同。 由于类不是运行时存在的对象。因此,在使用这类指针时,需要首先指定类的一个对象,然后,通过对象来引用指针所指向的成员。

声明

<数据类型>(<类名>::*<指针名>)(<参数列表>)

初始化

<数据类型>(<类名>::*<指针名>)(<参数列表>)=&<类名>::<非静态成员函数>

解引用

(<类对象名>.*<指向非静态成员函数的指针>)(<参数列表>)

(<类对象指针>->*<指向非静态成员函数的指针>)(<参数列表>)

实例:

#include <iostream>
using namespace std;
class Student
{
public:
    Student(string n, int nu):name(n),num(nu){}
    void dis()
    {
        cout<<"name:"<<name<<" num:"<<num<<endl;
    }
private:
    string name;
    int num;
};
int main()
{
    Student s("zhangsan",23);
    Student *ps = new Student("zhaoliu",35);
    
    void (Student::*pf)() = Student::dis;//指向类函数成员的指针  就这么定义,注意括号包起来::
    (s.*pf)();//解引用

    (ps->*pf)();//解引用
    return 0;
}

指向类静态成员的指针

指向静态成员的指针的定义和使用与普通指针相同,在定义时无须和类相关联,在使用时也无须和具体的对象相关联。

指针指向类成员变量数据成员

声明

<数据类型>*<指针名>

初始化

<数据类型>*<指针名>=& <类名>::<静态数据成员>

解引用

(*<指向静态数据成员的指针>)

指针指向类函数成员

声明

<数据类型>(*<指针名>)(<参数列表>)

初始化

<数据类型>(*<指针名>)(<参数列表>)=&<类名>::<静态成员函数>

解引用

(*<指向静态成员函数的指针>)(<参数列表>)

不举例子了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C语言面试题总结

    ①预处理 gcc -E a.c -o a.i ②编译 gcc -S a.c 生成a.s文件 ③汇编 gcc -c a.c 生成a.o文件 ④链接 gcc...

    用户5426759
  • C++多态的实现原理剖析

    首先放上结论:C++的多态是通过一张虚函数表(Virtual Table) 来实现的, 简称为 V-Table。 在这个表中, 主要是一个类的虚函数的地址表, ...

    用户5426759
  • 智能指针

    由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,...

    用户5426759
  • JUC并行计算框架 Fork/Join 原理图文详解&代码示例

    关键词:divide and conquer algorithm,work-stealing,WorkQueue

    一个会写诗的程序员
  • ArrayList源码和多线程安全问题分析

    代码改变世界-coding
  • 学术资讯 | 优Tech分享-3D结构光摄像头深度算法介绍

    光学和算法是3D结构光的核心能力,性能优越的3D结构光摄像头必须是光学系统和深度算法的完美融合,两者高度耦合且技术上不可分割。

    优图实验室
  • 548. 两数组的交 II 排序+双指针

    样例 nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2, 2].

    和蔼的zhxing
  • 设计模式之单例模式

    单例模式指的是在应用整个生命周期内只能存在一个实例。单例模式是一种被广泛使用的设计模式。他有很多好处,能够避免实例对象的重复创建,减少创建实例的系统开销,节省内...

    用户1205080
  • 07.LoT.UI 前后台通用框架分解系列之——强大的文本编辑器

    LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:h...

    逸鹏
  • 和233酱一起刷leetcode系列

    Leetcode这个网站上的题都是一些经典的公司用来面试应聘者的面试题,很多人通过刷这些题来应聘一些喜欢面试算法的公司,比如:Google、微软、Faceboo...

    Monica2333

扫码关注云+社区

领取腾讯云代金券