【C++精华铺】6.C++类和对象(下)类与对象的知识补充及编译器优化

目录

1. 再谈构造

1.1 成员变量的初始化(初始化列表)

1.2 初始化列表的行为

1.3 explicit关键字

 2. 类中的static成员

2.1 静态成员变量

2.2 静态成员函数

3. 友元

3.1 友元函数

3.1 友元类

4. 内部类

 5. 匿名对象

 6. 对象拷贝时候的编译器优化

 

1. 再谈构造

1.1 成员变量的初始化(初始化列表)

        为什么还要去看初始化的问题呢,因为这里有一个比较大的误区,我们都知道创建对象的时候会调用构造函数对成员进行初始化,所以我们会把下面的代码看作初始化,但其实下面的构造函数代码只能叫做赋值。

class Date
{
public:Date(int year,int month,int day){_year = year;   //因为初始化只有一次,_month = month; //而在函数里面可以多次赋值,不能叫做初始化_day = day;}
private:int _year;int _month;int _day;
};

        而真正的初始化是在初始化列表中进行的,初始化列表的位置是在构造函数”{}“的前面,是由一个冒号后面跟着多个用逗号隔开的成员变量,每个成员变量后面都有括号,括号里面就是初始值,初始化的次序与成员列表次序无关,是按照成员的声明顺序进行初始化,如下:

	Date(int year, int month, int day):_year(year),_month(month),_day(day){}

        而且像下面三种成员必须使用初始化列表进行初始化:

  1. const 成员变量:因为const成员具有常性不能进行赋值,而函数体是进行赋值的,所以只能在初始化列表进行初始化(具体与初始化列表的行为有关,待会叙述
  2. 引用成员变量:因为引用在定义的时候必须初始化,并且引用的实体不能更改,如果在函数体里进行,本质上是一个赋值重载。
  3. 没有默认构造的自定义类型:因为自定义类型会调用默认构造进行初始化,如果没有构造就必须显示的初始化。

1.2 初始化列表的行为

        我想大家应该都很困惑,为什么在初始化列表里面是初始化而在函数体里面就是赋值?初始化列表的执行时间是在函数体之前的,当我们调用构造函数的时候,编译器会首先去按照声明顺序进行默认的初始化,如果在初始化列表中有构造初始值则不会执行默认初始化,而去执行显式的初始化,所以无论我们有没有去写初始化列表,都是会在函数体执行之前初始化,这也就解释了为什么有些成员只能在初始化列表里面进行初始化和初始化列表的顺序与初始化顺序无关。而初始化列表对于编译器只是一个参考,可以认为编译器在执行的时候如果你(列表)有,我就按你的来,如果没有我就按照我自己的来。而const成员一旦执行了初始化就不能进行赋值,所以在语法上规定了const必须人为的给构造初始值,这也就是为什么const必须在初始化列表进行初始化了。

        而当我们执行到函数体的时候所有成员其实早就执行默认初始化初始化完成了,这个时候去进行所谓的”初始化“其实都是赋值(拷贝或者进行赋值重载)。

        无论什么时候我们都建议使用初始化列表进行初始化,首先就是不容易出错,其次就是规则上的统一。

1.3 explicit关键字

        如果构造函数只有单个参数或者除第一个参数无默认值其余均有默认值,在一些情况下会存在隐式类型转换。比如

class A
{
public:A(int a):_a(a){}
private:int _a;
};
//
class B
{
public:B(int a, int b = 1, int c = 1):_a(a),_b(b),_c(c){}
private:int _a;int _b;int _c;
};int main()
{A a1 = 1;  //这俩种情况都会发生隐式类型转换 转换成一个无名类型的对象进行拷贝B b1 = 1;//C++11B b2 = { 1, 2, 3}; //c++11支持的括号初始化,将数组进行类型转换再构造,            //想了解可以看我的c++11专栏}

23c9ecf132be4e57b0a78ea0b99255ae.png

         对于代码中提到的括号初始化可以看我的这一篇文章:【C++11】 统一的列表初始化( {}初始化 )_子亦半截诗的博客-CSDN博客

        回归正题,上述的这种类型转换有的时候我们并不希望发生,所以就有了explicit关键字,用这个关键字修饰构造函数,将不会发生这种类型转换,同时C++11的括号初始化特性也会被禁用。

class A
{
public:explicit A(int a):_a(a){}
private:int _a;
};
//
class B
{
public:explicit B(int a, int b = 1, int c = 1):_a(a), _b(b), _c(c){}
private:int _a;int _b;int _c;
};
int main()
{A a1 = 1;  //报错:E0415	不存在从 "int" 转换到 "A" 的适当构造函数B b1 = 1;  //报错:E0415	不存在从 "int" 转换到 "B" 的适当构造函数//C++11B b2 = { 1, 2, 3 };   //报错:E2334	复制列表初始化不能使用标记为“显式”的构造函数
}

 报错:c5bc0a3024c047f48e01265fc3cd5e8f.png

 

 2. 类中的static成员

        类中的静态成员和类中其他的成员有很大的区别,非静态成员变量的初始化在初始化列表里面进行,但是静态成员变量不能在初始化列表中初始化,因为static成员并不属于某个对象,static成员被存放在静态区,被同类型的所有对象共享

2.1 静态成员变量

        静态成员变量属于同类型的所有对象,它的定义和初始化在类外进行。在定义的时候需要在变量名前面加上 类名:: 。

int A::_a = 0;
class A
{
public:
private:static int _a;
};

2.2 静态成员函数

        由于静态函数属于每一个类对象,而不属于某个对象,所以静态成员函数也就没有this指针,所以也就不能访问类的非静态成员。非静态成员函数可以调用静态成员函数,但是静态成员函数不能调用非静态函数。可能有人要疑问了:非静态成员函数不也是被共享的吗,为什么不能被静态成员函数访问呢?这是因为非静态成员函数需要传入this指针,而静态成员函数是没有this指针的。

int A::_a = 0;
class A
{
public:static void test() {  }void test1() { test(); }
private:static int _a;
};

3. 友元

        友元是一种突破封装的方式,让外部成员访问自己私有成员的一种方式,但过度使用会破坏封装。

3.1 友元函数

        友元函数的声明就是在类中声明函数时在前面加上friend关键字,声明成友元函数这个函数就能访问对象的私有成员。在一些特殊情况下需要使用,就比如”<<“流写入符号重载,由于"<<"的左操作数必须是ostream对象,所以第一个参数就必须是ostream类型,但是如果定义成成员函数,第一个参数就变成this指针了,这会导致我们使用”<<“的时候就变成” 对象<<cout  “,这与我们的习惯就不符,所以流写入的符号重载必须定义成全局函数,而且还必须要能访问类的私有成员,这个时候友元函数就可以发挥作用了。如下:

class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);
private:int _year;int _month;int _day;
};ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << ' ' << d._month << ' ' << d._day << endl;return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{_cin >> d._year;_cin >> d._month;_cin >> d._day;return _cin;
}
  •  友元函数可以访问类的所有成员,但不是类的成员
  • 友元函数不可以用const修饰
  • 友元函数不受访问限定符限制

3.1 友元类

        如果一个类A声明了一个友元类B,那么B类中的所有成员都可以访问A类的所有成员,但A类不能访问B类的成员。友元关系不能传递和继承(继承以后再说),比如C是D的友元,D是E的友元,但C不是E的友元。

class A
{friend class B;
private:int _aa;int _ab;int _ac;
};
class B
{void print(){cout << _atest._aa << ' ' << _atest._ab << ' ' << _atest._ac << endl;}private:A _atest;
};

4. 内部类

        当一个类定义在另一个类的内部,这个类就被称之为内部类。内部类相当于外部类的友元类,可以通过对象参数访问内部类中的所有成员,访问静态成员的时候不需要对象参数就可以直接访问,但是外部类不能访问内部类的成员。内部类是一个独立的类,对外部类的大小没有任何影响。外部成员对内部类的访问会受到访问限定修饰符的限制。

class A
{
public:class B{void print(const A& a){cout << a._a;}};
private:int _a;
};

 5. 匿名对象

        匿名对象的定义就是在对象后面加上一个括号,匿名对象不用取名字,声明周期也只有一行,使用完后就自动调用析构函数销毁了。

class A
{
public:static int _a;
};
int A::_a = 0;int main()
{A();   //匿名对象cout << A()._a;
}

 6. 对象拷贝时候的编译器优化

        在我们传参或者传值返回的时候可能会进行频繁的构造和拷贝构造,如果对象较大,会造成极大的资源消耗,所以为此编译器做出一些优化。(只针对构造,赋值重载不会进行优化)

class A
{
public:A(int a = 0){cout << "A(int a = 0)" << endl;}A(const A& aa){cout << "A(const A & aa)" << endl;}~A(){cout << "~A()" << endl;}
};
void f1(A a)
{}
A f2()
{A a;return a;
}
int main()
{A a;f1(1);  //连续构造+拷贝构造->直接构造f1(A(2)); //连续构造+拷贝构造->直接构造A a1 = f2(); //拷贝构造+拷贝构造->优化为一个拷贝构造
}

a385f1784f714926b72221a51c924dcd.png

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1380220.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

C语言案例 球落地反弹-10

题目&#xff1a;一球从100米高度自由落下&#xff0c;每次落地后反跳回原高度的一半;再落下&#xff0c;求它在第10次落地时&#xff0c;共经过多少米第10次反弹多高&#xff1f; 程序分析 球在落地后会反弹为原高度的一半&#xff0c;若设高度为h&#xff0c;那么每次落地的…

C++初阶语法——类和对象

前言&#xff1a;C语言中的结构体&#xff0c;在C有着更高位替代者——类。而类的实例化叫做对象。 本篇文章不定期更新扩展后续内容。 目录 一.面向过程和面向对象初步认识二.类1.C中的结构体2.类的定义类的两种定义方式 3.类的访问限定符及封装访问限定符说明 4.类的实例化对…

NIDS网络威胁检测系统-Golang

使用技术&#xff1a; Golang Gin框架 前端三件套 演示画面&#xff1a; 可以部署在linux和window上 目前已在Kali2021和Window10上进行测试成功

AI:03-基于深度神经网络的低空无人机目标检测图像识别的研究

文章目录 数据集收集与预处理深度神经网络模型设计模型训练与优化目标检测与图像识别代码实现:实验结果与分析讨论与展望低空无人机的广泛应用为许多领域带来了巨大的潜力和机会。为了实现无人机的自主导航和任务执行,准确的目标检测和图像识别是至关重要的。本文旨在研究并提…

Android全品类源码大全

先来看看有哪些类型的Android源码&#xff0c;如图&#xff1a; 下面奉上这些源码的下载地址&#xff1a; textView.rar: https://url25.ctfile.com/f/34512525-690088932-bd9744?p7054 (访问密码: 7054) UI布局.rar: https://url25.ctfile.com/f/34512525-690088945-59cd16…

基于SSM实现的网上手机商城项目(附源码)

基于SpringSpring MVCMyBatisLayui框架 项目完整源码下载 https://download.csdn.net/download/DeepLearning_/87327169 功能&#xff1a; 前台 登录、注册、注销查看商品、商品评论、热销商品收藏、取消收藏商品加入购物车购物车增、删、改、查购买商品、确认收货、删除已…

【附源码】Java计算机毕业设计的手机电商网站(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; java mybatis Maven等等组成&#xff0c;B/S模式 Maven管理等…

sudo root命令不在sudoers文件中。此事将被报告。全网比较详细版本,解决报错问题步骤较多

我在使用个人用户zhang&#xff08;非root用户&#xff09;时&#xff0c;在执行其他命令时&#xff0c;使用sudo命令来执行的时候&#xff0c;需要验证当前用户的密码&#xff0c; 输入了之后&#xff0c;提示“zhang‘ 不在sudoers文件中&#xff0c;此事将被报告” 分析原…

java电商网站源码带前后台

&#x1f353;&#x1f353;文末获取联系&#x1f353;&#x1f353; 项目描述 该网站包含前台购物流程、个人中心展示、后台管理这三个大类组成&#xff0c;实现流畅的购物体验。前台购买—>个人中心查看—>后台发货的基本购物流程。 运行环境 myeclipsemysqlTomcat …

旧物回收类网站源码系统(带手机) v1.6.1

链接&#xff1a;https://pan.baidu.com/s/1BMwaycuJx0eV7pxmcXuDpA?pwddsxr 提取码&#xff1a;dsxr 功能介绍 旧物回收类网站源码系统是一款开源的THinkphp5.0 的 Blog系统&#xff0c;其衍生于优秀的内容管理系统易优cms。 旧物回收类网站源码系统秉承了易优CMS的先进设计…

2022最新H5手机微商城运营源码 简约轻量版 对接最新Z支付个人免签接口 带搭建教程

很简约的一款手机微商城源码&#xff0c;只具备下单出单&#xff0c;商品售卖&#xff0c;订单查询等基础功能&#xff0c;身边朋友托我找的一款微商城源码&#xff0c;要求就是不要那些优惠券秒杀倒计时的这些。搭建很简单&#xff0c;也无需授权。 测试环境&#xff1a; Ngi…

计算机毕业设计PHP的手机电商网站(源码+程序+VUE+lw+部署)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; phpStudy Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; 原生PHP Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环…

基于nodejs手机网页端购物电商系统.rar(含源码)

该商城shop是一个nodejs写的商城系统&#xff0c;。目前功能首页&#xff0c;商品搜索&#xff0c;购物车&#xff0c;我的&#xff0c;登录&#xff0c;商品详情&#xff0c;结算等&#xff0c;网站手机端网页程序&#xff0c;适合毕业设计以及商用二次开发&#xff0c;前端&a…

9个主流影视站手机仿站源码分享 v1.0

介绍&#xff1a; 九种主流视频APP风格仿站手机影视网站程序&#xff0c;页面精美&#xff0c;基于PHP开发&#xff0c;无需数据库&#xff1b; 源码代码简洁清晰&#xff0c;完全免费无后门&#xff0c;简单上传即可使用&#xff0c;自定义解析播放接口&#xff1b; 源码所有…

基Android实现网上商城的系统开发(附带源码)

主要代码 HomeActivity.java 代码如下&#xff1a; package com.itau.jingdong.ui; import android.app.AlertDialog; import android.app.Dialog; import android.app.TabActivity; import android.content.DialogInterface; import android.content.DialogInterface.OnCli…

[附源码]计算机毕业设计基于Springboot的手机电商网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Destoon7.0绿色行业B2B大气平台门户全站源码/带手机版+商务中心网站商城系统源码

非常大气的一套destoon系统&#xff0c;适用于各种B2B行业网站&#xff0c;功能强大完善&#xff0c;带商务会员中心&#xff01;Destoon7.0内核&#xff0c;带安装说明&#xff0c;并附赠火车头采集接口以及185套公司模板。站长亲测非常完美&#xff0c;有需要的下载吧。 下载…

(纯原创) 基于JAVAWEB的网上购物平台(完整源代码以及开发文档)

摘要 随着计算机网络技术的飞速发展和人们生活节奏的不断加快&#xff0c;电子商务技术已经逐渐融入了人们的日常生活当中&#xff0c;网上商城作为电子商务最普遍的一种形式&#xff0c;已被大众逐渐接受。因此开发一个网上商城系统&#xff0c;适合当今形势&#xff0c;更…

【android精品源码系列】安卓线上购物商城

安卓线上购物商城【源码推荐】 简介效果演示首页分类购物车我的 获取方式关于我 简介 分享一个非常优秀的Android商城&#xff0c;功能非常完备&#xff0c;主要功能有&#xff1a; 1.首页不同item展示商品&#xff0c;轮播图等2.商品详情立即购买和加入购物车3.商品的分类&a…

Android在线源码网站推荐

Android开发过程中调用的Android SDK中framework jar提供的源码&#xff0c;这部分不包括hide的内容和非framework的代码&#xff0c;但解决一般的问题可以尝试使用此方式。 1、http://aospxref.com/ 优点&#xff1a;更新速度快 缺点&#xff1a;历史版本较少 2、http://an…