C++ 7.7 类的成员函数、this 指针、默认构造函数、默认初始化(总结)

本文介绍了C++中this指针的概念及其在成员函数中的应用,同时详细讲解了构造函数的定义与使用,包括初始化列表和默认构造函数等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

this 指针

  • 每个成员函数都有一个额外的、隐含的形参–this指针,这个指针指向的是调用函数的对象的地址。(除了在12.6节介绍的static成员函数外)

const 成员函数

  • 定义类时,声明的成员函数后面有一个const——const 成员函数

  • 这个const所起的作用:const改变了隐含的this 形参的类型。

  • 用这种方式使用const的函数称为常量成员函数。由于this是指向const对象的指针,const成员函数不能修改调用该函数的对象。因此,函数avg_price和函数same_isbn只能读取而不能修改调用他们的对象的数据成员。

  • 在类的定义外面定义成员函数必须指明它们是类的成员!
    * double Sale_item::avg_price() *

默认构造函数

  • 对于具有类类型的成员,如string类型的isbn ,则会调用该成员所属类自身的默认构造函数实现初始化,初始化为空串;

  • 内置类型成员的初值依赖于对象如何定义,如果对象在全局作用域中定义(即不在任何函数中)或定义为静态局部对象,则这些成员将被初始化为0。

  • 如果对象在局部作用域中定义,则这些成员没有初始化。

===============================================================================================================================

一、类的成员函数

1、成员函数的定义

  • 成员函数也包含以下四个部分:

    • 函数返回类型;
    • 函数名
    • 用逗号隔开的形参表(可能是空的);
    • 包含在一对花括号里面的函数体
  • 前面三部分组成函数原型,函数原型定义了所有和函数相关的类型信息:函数返回类型是什么、函数的名字、应该给这个函数传递什么类型的实参。

  • 函数原型必须在类中定义。

  • 函数体则既可以在类中也可以在类外定义

class Sale_item{
public:
     double avg_price() const;//函数声明,形参表为空,返回double类型的值,const说明这是一个const成员函数
     bool same_isbn(const Sale_item &rhs) const  
     //返回bool类型值,有一个const Sale_item类型的引用
     {return isbn==rhs.isbn;}
private:
    std::string isbn;
    unsigned units_sold;
    double revenue;
};

二、定义成员函数的函数体

  • 类的所有成员都必须在类定义的花括号里面声明,此后,就不能再为类增加任何成员;

  • 类的成员函数必须如声明的一般定义,类的成员函数既可以在类的定义内定义也可以在类的定义外定义;

  • 编译器隐式地将在类内定义的成员函数当作内联函数;

  • 类的成员函数可以访问该类的private成员。

1、成员函数含有额外的、隐含的形参

调用成员函数需要使用对象来调用。在上面的类定义的基础上。

total.same_isbn(trans);//传递对象trans,使用对象trans初始化rhs,于是,rhs.isbn是trans.isbn的引用。

2、this指针的引入–成员函数隐含的形参

  • 每个成员函数都有一个额外的、隐含的形参–this指针,这个指针指向的是调用函数的对象的地址。(除了在12.6节介绍的static成员函数外)

  • 在本节定义的这个类里边,成员函数 bool same_isbn(const Sale_item &rhs) const 里面就有一个形参this 指针,看下面3

total.same_isbn(trans);

就如编译器这样重写这个函数调用:

Sale_item::same_isbn(&total,trans);//在这个调用中,函数same_isbn中的数据成员isbn属于对象total

3、const成员函数的引入

  • 定义类时,声明的成员函数后面有一个const——const 成员函数

  • 这个const所起的作用:const改变了隐含的this 形参的类型。如下:

  • 因为same_isbn成员函数后面有一个const,所以在调用total.same_isbn(trans)时,隐含的this形参将是一个指向total 对象的const Sale_item * 类型的指针same_isbn函数可以像如下编写:

bool Sale_item::same_isbn(const Sale_item * const this,//指向某个const对象的const Sale_item * 类型的指针
                          const Sale_item & rhs)const

{ return (this->isbn == rhs.isbn);}
  • 用这种方式使用const的函数称为常量成员函数。由于this是指向const对象的指针,const成员函数不能修改调用该函数的对象。因此,函数avg_price和函数same_isbn只能读取而不能修改调用他们的对象的数据成员。

  • const对象、指向const对象的指针或引用只能用于调用其const成员函数,如果尝试用他们累调用非const成员函数,则是错误的。

4、this 指针的使用

  • 在成员函数中,不必显示地使用this 指针来访问被调用函数所属对象的成员,对这个类的成员的任何没有前缀的引用,都被假定为通过指针this 实现的引用;

  • 由于this 指针是隐式定义的,因此不需要在函数的形参表中包含 this 指针,实际上,这样做是非法的。但是,在函数体中可以显示地使用this 指针。

bool same_isbn( const Sale_item & rhs)const

{ return isbn==rhs.isbn;}//在这个函数中,isbn 的用法与this ->units_sold 或 this ->revenue 的用法一样。
bool same_isbn( const Sale_item & rhs)const

{ return this->isbn==rhs.isbn;}

二、在类外定义成员函数

在类的定义外面定义成员函数必须指明它们是类的成员!!!
double Sale_item::avg_price() const{
   if(units_sold)
      return revenue/units_sold;
   else
      return 0;      
}
  • Sale_item::avg_price() 使用作用域操作符指明函数 avg_price() 是在类Sale_item 的作用域范围内定义的。
  • 形参后面的const则反映了在类Sale_item 中声明成员函数的形式。

  • 在任何函数定义中,返回类型和形参表必须和函数声明(如果有的话)一致。

  • 对于成员函数,函数声明必须与其定义一致。

  • 如果函数被声明为const 成员函数,那么函数定义时形参表后面也必须有const。

  • 理解第一行代码,这行代码说明现在正在定义类Sale_item 的函数avg_price() 。而且这是一个const 成员函数,这个函数没有(显示的)形参(但有隐式的this 指针形参),返回double类型的值。

三、编写Sale_item类的构造函数

在定义类时,没有初始化它的数据成员的,都是通过构造函数来初始化其数据成员的。

1、构造函数是特殊的成员函数——和类同名,没有返回类型
  1. 构造函数是特殊的成员函数,与其他成员函数不同,构造函数和类同名,而且没有返回类型。而与其他成员函数相同的是,构造函数也有形参表(可能为空)和函数体。

  2. 一个类可以有多个构造函数,每个构造函数必须有与其他构造函数不同数目或类型的形参。

  3. 构造函数的形参指定了创建类类型对象时使用的初始化式。通常,这些初始化式会用于初始化新创建对象的数据成员。

  4. 构造函数应该确保每个数据成员都完成了初始化。

  5. 默认构造函数:没有形参的函数,表示当定义了一个对象却没有为它提供(显示的)初始化式时应该怎么办。

vector<int> vi;//vector默认构造函数生成一个没有元素的vector向量对象
string s;      //string 的默认构造函数会产生空的字符串,相当于“ ”
Sale_item item;//默认初始化item对象,isbn初始化为空的字符串,units_sold和revenue初始化为0.
2、构造函数的定义
  • 和其他成员函数一样,构造函数必须在类中声明,但可以再类中或类外定义。

  • 构造函数必须放在类的public 部分

class Sale_item{
public:
     double avg_price() const;//函数声明,形参表为空,返回double类型的值,const说明这是一个const成员函数
     bool same_isbn(const Sale_item &rhs) const  
     //返回bool类型值,有一个const Sale_item类型的引用
     {return isbn==rhs.isbn;}
     Sale_item(): units_sold(0),revenue(0){}//显示定义一个构造函数
private:
    std::string isbn;
    unsigned units_sold;
    double revenue;
};
Sale_item(): units_sold(0),revenue(0){}//构造函数,函数体和形参为空,形参为空表明正在定义的是默认调用的构造函数,不需要提供任何初值。
3、构造函数的初始化列表
Sale_item(): units_sold(0),revenue(0){}//构造函数,函数体和形参为空,形参为空表明正在定义的是默认调用的构造函数,不需要提供任何初值。
  • 在冒号和花括号之间的代码称为 构造函数的初始化列表。

  • 构造函数的初始化列表为类的一个或多个数据成员指定初值。它跟在构造函数的形参表之后,以冒号开头。

  • 构造函数的初始化式是一系列成员名,每个成员后面是括在圆括号中的初始值,多个成员的初始化用逗号分隔。

4、合成的默认构造函数
  • 如果没有为一个类显示定义任何构造函数,编译器会自动为这个类生成默认构造函数

  • 编译器创建的默认构造函数通常称为 合成的默认构造函数,它会依据如同变量初始化的规则初始化类中所有成员

  • 对于具有类类型的成员,如string类型的isbn ,则会调用该成员所属类自身的默认构造函数实现初始化,初始化为空串;

  • 内置类型成员的初值依赖于对象如何定义,如果对象在全局作用域中定义(即不在任何函数中)或定义为静态局部对象,则这些成员将被初始化为0。

  • 如果对象在局部作用域中定义,则这些成员没有初始化。

  • 除了给它们赋值之外,出于其他任何目的的对未初始化成员的使用都没有定义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值