当前位置: 首页 > news >正文

【C++入门】类与对象(3)

目录

1. const成员

1.1 &重载函数

  1.2 const函数使用的时机

2. 再谈构造函数

  2.1 初始化列表的意义?

2.2 初始化列表题目

2.3 三种创建对象的方式(栈)

2.4 explicit关键字

3. static成员


1. const成员

首先看四个问题:

①const对象可以调用非const成员的函数吗?

②非const对象可以调用const成员函数吗?

③const成员函数内可以调用其它的非const成员函数吗?

④非const成员函数内可以调用其它的const成员函数吗?

这里很像绕口令,不过没关系,我们可以先看下面的代码,最后再来解答这四个问题。

class Date
{
private:int year;int month;int day;public:void f1() // Date* this{f2(); // f2(this)}void f2() const // const Date* this 权限缩小{}void f3() {} // Date* thisvoid f4() const // const Date* this{f3(); // f3(this) 权限放大,错误}
};

        上面有四个成员方法,我们在上一期讨论过,f1()的调用是因为形参中有一个this指针,例如f1(Date* this),这个指针很重要, void f2() const 其实等价于 void f2(const Date* this),保证this指针指向的对象是不能被改变。

        首先我们看f1,调用f2,f2(Date* this),此时this指针权限是最大的,因为没有const修饰,传入我们可以看到f2的形参是有const修饰的,其实就是将大权限变成小权限的形参,这里只是进行权限缩小,所以没有问题;

        我们再看f3,f3的形参没有const修饰,所以此时形参的权限最大,f4的this指针是const Date* this,作为实参传入f3的形参,此时权限进行了放大,这里一定会有问题。

        我们再来回答四个问题:

①const对象可以调用非const成员的函数吗? NO,this指针权限进行放大

②非const对象可以调用const成员函数吗?     YES,this指针权限缩小

③const成员函数内可以调用其它的非const成员函数吗? NO,this指针权限放大

④非const成员函数内可以调用其它的const成员函数吗? YES,this指针权限缩小

1.1 &重载函数

        当我们取地址对象其实是在调用下面的重载函数。

Date* operator&()  // 形参Date* this
{return this;
}

        当我们调用d2的地址的时候,此时会存在问题,d2的类型是const Date 传入形参中会造成权限扩大,所以我们还可以对上面的&重载函数进行重载,具体如下:

const Date* operator&() const 
{return this;
}

  1.2 const函数使用的时机

        一句话总结,只要成员变量不改变,无脑加const,类似于,void fuc () const ,这样const对象或者非const对象都能调用这个函数。

2. 再谈构造函数

        构造函数中给成员变量赋值,除了可以使用构造函数函数体中进行赋值,还可以使用初始化列表,这个方法,具体操作如下:就在方法的后面,成员变量(),中间使用逗号分隔。

Date() :year(10),month(1),day(20)
{}

  2.1 初始化列表的意义?

引用成员变量、const 成员变量、没有默认构造函数的对象的初始化必须使用初始化列表。

        我们可以理解初始化列表就是成员变量定义的地方。引用和const成员变量以及没有默认构造函数的对象都必须在定义的时候初始化,所以这就很好理解了。

2.2 初始化列表题目

        这里看初始化列表的初始化顺序,这里会先初始化a2,因为a2先声明,此时a1的值是随机值,所以a2就是随机值,a1被赋值为1,此时输出1 随机值,选D。

2.3 三种创建对象的方式(栈)

        前面我们学过可以使用构造函数进行构造对象,也可以使用拷贝构造函数构造对象,今天来介绍另外一种构造对象的方式,那就是隐式类型转换:

Date d1(1); // 构造函数
Date d2 = d1;// 拷贝构造
Date d3 = 1; // 隐式类型转换 Date tmp(1) -> d3 = tmp;

其实就是创造了一个临时变量,tmp,再使用拷贝构造函数进行初始化对象。类似于:

int i  = 10;
double j = i; 
/*
事实上是const double tmp = i;这里的const是因为临时变量具有常性
j = tmp;如果使用
double& j = i;
就会报错,这是因为其实将 const double 给了引用,如果想要不报错
const double& j = i; 
*/

如果参数不止一个,例如构造函数中有三个形参,在C++11中可以使用下面的代码进行构造,也是隐式类型转换。

Date(int year,int month ,int day):a(year),ref(month),c(day)
{}int main(){Date d = { 1,2,3 }; // c++11中可以批量隐式类型转换
}

2.4 explicit关键字

        2.3中讲述了Date d = 1;这里其实是隐式类型转换,如果不想让这个隐式类型转换发生,这里可以在构造函数前面加上explicit关键字,阻止隐式类型转换的发生

3. static成员

        设计一个类,计算这个类总计产生了多少个对象。

        对象的产生一定是构造函数或者拷贝构造函数产生的,所以可以定义一个静态的成员变量用于计算对象。

class A
{
private:
public:static int cnt;A(){cnt++;}A(const A& a) {cnt++;}};
A f1(A a)
{return a;
}
int A::cnt = 0;// 初始化int main() 
{A a1;A a2;f1(a1);f1(a2);cout << a1.cnt << endl;
}

答案是6,因为a1、a2会使用构造函数2次,调用函数的时候传入形参会调用拷贝构造,返回值的时候依然会调用拷贝构造函数,所以1 + 1 + 2 + 2 = 6;

        此时将f1的返回值换成引用,那么此时的值就是4,因为返回值就不需要调用拷贝构造了。

         使用static修饰成员方法,这个方法没有this指针,所以就不能访问非静态的成员变量。

http://www.dtcms.com/a/413105.html

相关文章:

  • 福建省网站备案设计师服务平台网站
  • 做网站选哪个语言热门网络游戏
  • 互站网源码商城站点创建成功有影响吗
  • 网站开发设计体会如何备份网站数据库
  • 买了一台配置强悍的电脑怎么做网站服务器做外贸怎么做
  • 网站flash效果广安发展建设集团有限公司门户网站
  • Linux内核进程管理子系统有什么第六十一回 —— 进程主结构详解(57)
  • 淮安市建设工程质量监督站网站git wordpress主题
  • 太平洋建设21局网站域名访问wordpress
  • 徐汇郑州阳网站建设dz网站首页html代码在哪
  • 网站建设报告模板wordpress搭建淘宝客
  • 公司建立网站费用云南网站建设优化
  • wordpress ip镇江网站建设方式优化
  • 24小时网站建设阿里云网站建设部署与发布
  • 网站建设实训不足怎样建设一个韩国网站
  • 定制制作网站开发oa系统登录入口
  • 陇南地网站seo开网站做商城怎么样
  • 网站建设高端培训ppt设计大赛
  • 网站推广的方法及特点wordpress功能介绍
  • 考试报名费悦生活建设银行网站淘宝店铺怎么运营
  • 撰写网站规划书网站建站平台排行榜
  • daily notes[56]
  • 盐城做网站找哪家好建设好网站能赚到钱吗
  • 有哪些网站可以做青旅义工wordpress加目录
  • 企业网站模板演示德州手机网站建设报价
  • 鄱阳县精准扶贫旅游网站建设目的用ps个人网站怎么做
  • 做网站需要公司么业之峰家装公司地址
  • 快速收录网站微信开发者工具有什么作用
  • 查钓鱼网站seo优化排名百度教程
  • 虹口专业做网站网站建设预算描述