C++类与对象知识整理

类的定义

class className
{
// 类体:由成员函数和成员变量组成
};
这是定义类的一般形式,class为类的关键字,className为类的名字(可自定义名字),{}两个大括号中放的就是类体,由成员函数成员变量组成。**这里一定注意类定义结束时的;**在类体外定义成员时需使用::作用域解析符指明这个成员属于哪个类。
类的两种定义方式:
1.声明和定义全放在类体中,主要指成员函数,在类体中定义会被编译器当成内联函数。内联函数编译时,类似宏替换,使用函数体替换调用处的函数名。
2.声明放在.h文件中,定义放在.cpp文件中。

类的访问限定符及封装

通过访问限定符选择性的将接口提供给外部用户使用。
访问限定符包括有:

  • public(公有)
  • private(私有)
  • protected(保护)

访问限定符的使用规则:

  • public修饰的成员可以在类外访问到
  • private和protected修饰的成员在类外不能被直接访问到
  • 访问限定符的作用域从该访问限定符出现的位置到下一个访问限定符的出现的位置
  • class的默认访问权限是private,struct的默认访问权限是public。
    封装:
    面向对象的三大特性:封装、继承、多态
    在类与对象学习时只研究封装,封装通过类+访问限定符来实现管理
    封装是将数据和操作数据的方法有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

类的实例化

  • 类只相当于一个模型,限定了类有哪些成员,并没有给类分配内存空间
  • 类的实例化是定义类类型的变量,一个类可实例化出多个对象,这个对象占用物理空间,分配内存空间,存储类类型的变量。

类的大小

类的大小和成员变量有关:所有成员变量的大小总和+内存对其原则

  • 空类占多大字节呢?
    类本身不占空间,但空类可以实例化对象,而对象是占空间的,所以给1个字节的大小。
  • 类中定义的函数存放在代码段,不占类的大小

this指针

c++编译器给每个成员函数增加了一个隐含的指针this指针,放在第一个形参的位置上,其指向当前对象(调用该函数的对象),在函数体中所有成员变量的操作,都通过this指针访问到。这个参数不需要用户来传递,编译器自动完成。
this指针的特性

  • this指针的类型:类类型* const
  • 调用类中函数时,函数的第一个形参是指针this,this存放的地址是对象的地址
  • this值存放在栈上,优化的话,存在ecx的寄存器上
  • this指针若不做解引用,则可以为空
  • this指针只能在成员函数内部使用

类的6个默认成员函数

构造函数、析构函数、运算符重载函数、拷贝构造函数、取地址运算符重载函数(分为普通对象和const对象取地址)
如果一个类中什么都没有,即空类。那么它会自动生成上面的6个默认成员函数。

构造函数

构造函数是特殊的成员函数,名字与类名相同,在创建类类型的对象时,由编辑器自动调用,对对象进行初始化。
其特征是:

  • 无返回值
  • 函数名与类名相同
  • 可重载
  • 在对象实例化时,编辑器自动调用构造函数
    构造函数又分为无参数、可缺省、系统默认构造函数(编辑器默认生成)、带参构造函数。其中无参构造函数、全缺省构造函数、系统默认构造函数都是默认构造函数。而默认构造函数只能有一个。
    如果我们不写构造函数,那么系统也会生成一个默认构造函数,但其初始化值为随机值。那么编辑器生成的默认构造函数有什么用呢?当成员变量中有自定义成员时,编辑器默认生成的构造函数能够对自定义成员_t调用它的默认构造函数。如代码所示
    class Time
    {
    public:
    Time()
    {
    cout << “Time()” << endl;
    _hour = 0;
    _minute = 0;
    _second = 0;
    }
    private:
    int _hour;
    int _minute;
    int _second;
    };
    class Date
    {
    private:
    // 基本类型(内置类型)
    int _year;
    int _month;
    int _day;
    // 自定义类型
    Time _t;
    };
    int main()
    {
    Date d;
    return 0;

析构函数

析构函数:在销毁对象之前,清空资源,编辑器会自动调用。
其特征是:

  • 函数名只在类名前加~
  • 无参数无返回值
  • 不可重载,只有一个析构函数
  • 在对象生命周期结束时,编辑器自动调用析构函数,若没有显示定义,编辑器自动生成析构函数。
  • 同样对于自定义成员,编辑器默认生成的析构函数会调用自定义成员的析构函数

拷贝构造函数

   例:Date(Date& d){ }
  • 是构造函数的重载形式。
  • 只有一个参数,且必须使用引用传参,使用传值会引发无穷递归调用。
  • 若未显示定义,系统会生成默认拷贝构造函数,完成字节序的拷贝,这个拷贝是浅拷贝,或值拷贝。但当成员变量中有指针变量时,默认的拷贝构造会将此地址再拷贝一份给新对象的指针变量赋值,也就是说这两个指针指向同一个地址空间。当两个对象的生命周期结束时,分别会调用一次析构,共调用两次对这个内存进行释放,程序会崩溃。所以需要自己写拷贝构造函数,完成深拷贝。

赋值运算符重载函数

1运算符重载

为了增强代码的可读性,c++引入了运算符重载。
函数名为:operator操作符
函数原型为:返回值类型 operator操作符(参数列表)
例:bool operator==(const Date& d1,const Date& d2)
在调用时可以直接d1==d2;
其特征是:

  • 不能通过连接其他符号来创建新的操作符
  • 重载操作符,其参数必须有一个自定义类型或枚举类型
  • 不能改变内置类型的操作符含义,如+
  • 作为类成员函数时,其形参第一个默认的是this指针,所以形参看起来比操作数目少1
  • .* 、:: 、sizeof 、?: 、. 以上5个运算符不能重载
2赋值运算符重载
 例
 Date& operator=(const Date& d)
 {
 if(this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
}

1 检测是否自己给自己赋值
2. 返回*this
3. 一个类如果没有显式定义赋值运算符重载,编译器也会生成一个,完成对象按字节序的值拷贝。浅拷贝,当有资源的时候,也会出现问题

const成员函数

例  void display()const
const实际是这么修饰的:const 类名*this

指的是this指针指向的内容不能修改,内部不能调用非const成员函数,而非const可调用任意成员函数。

取地址运算符重载函数

class Date
{
public :
Date* operator&()
{
return this ;
}

const Date* operator&()const
{
return this ;
}
private :
int _year ; // 年
int _month ; // 月
int _day ; // 日
};
这两个一般不需要重载,编辑器会默认生成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值