浅谈C++|类的成员

一.类对象作为类成员

类可以作为另一个类的成员

代码: 

#include <iostream>
using namespace std;
class phone {
public:string shouji;phone(string shouji1) :shouji(shouji1) {cout << "phone的构造函数调用" << endl;}~phone() {cout << "phone的析构函数调用" << endl;}
};
class person {
public:int age;string name;phone shouji;//隐式转换相当于shouji=phone(shouji1)person(int a, string name1, string shouji1) :age(a), name(name1), shouji(shouji1) {cout << "person的构造函数调用" << endl;}~person() {cout << "person的析构函数调用" << endl;}
};
void fun() {person p(23, "小明", "苹果");
}
int main() {fun();return 0;
}

 注意:

创建类时,被包含的类的构造函数先调用,随后外层类的构造函数再调用,析构1的时候正好相反,外部类先析构,内部类再析构。

二.静态成员 

静态成员就是在成员变量前面加上static关键字,称为静态成员。

静态成员分为静态成员变量静态成员函数

2.1静态成员变量

。所有对象共享同一份数据

。在编译阶段分配内存。

类内声明,类外初始化·静态成员函数

 静态成员必须在类外初始化,否则编译器认为只声明,但是没有实际定义,链接发生错误。

代码: 

#include <iostream>
using namespace std;
class person {
public:static int age;
};
int person::age = 10;
void fun() {person p;p.age = 90;person p1;cout << p1.age << endl;
}
int main() {fun();return 0;
}

 静态成员变量,不仅可以通过对象访问,也可以通过类名访问。静态成员变量也是有访问权限的。

代码: 

#include <iostream>
using namespace std;
class person {
public:static int age;
};
int person::age = 10;
void fun() {person p;p.age = 90;cout << person::age << endl;
}
int main() {fun();return 0;
}

2.2静态成员函数

。所有对象共享同一个函数

静态成员函数只能访问静态成员变量

代码: 

#include <iostream>
using namespace std;
class person {
public:static int age;static void fun(int a) {age = a;          //只能调用静态成员变量cout << "静态函数fun调用" << endl;}
};
int person::age = 100;
void dioayong() {person p;p.fun(99);          //对象调用person::fun(66);   //类名调用cout << p.age << endl;
}
int main() {dioayong();return 0;
}

同样,静态成员函数也是可以通过类名来调用,需要注意静态成员函数只能调用静态成员变量。

 三.this指针

3.1成员变量和函数的存储

在C++中,类内的的成员变量和成员函数分开存储

只有非静态成员变量才属于类的对象上

在C++中, 空类也占用一个字节。C++编译器会给每个空对象也分配一个字节空间,是为了区分对象占内存的位置

代码: 

#include <iostream>
using namespace std;
class person {};
void fun() {person p;cout<<sizeof(p);
}
int main() {fun();return 0;
}

 在类中同样具有内存对齐的特性

代码: 

#include <iostream>
using namespace std;
class person {
public:int a;char b;
};
void fun() {person p;cout<<sizeof(p);
}
int main() {fun();return 0;
}

 此外,成员函数和静态成员变量都不存储在类上,也就是只有非静态成员变量存储在类中

代码: 

#include <iostream>
using namespace std;
class person {
public:int a;static int b;void fun() {cout << "fun函数调用" << endl;}static void fun1() {cout << "fun1函数调用" << endl;}
};
int person::b = 10;
void fun() {person p;cout<<sizeof(p);
}
int main() {fun();return 0;
}

 3.2this指针使用

每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码那么问题是:这一块代码是如何区分那个对象调用自己的呢?

C++通过提供特殊的对象指针,this指针,解决上述问题。this指针指向被调用的成员函数所属的对象

 注意:

1.this指针是隐含每一个非静态成员函教内的一种指针

2.this指针不需要定义,直接使用即可

this指针的用途: 

·当形参和成员变量同名时,可用this指针来区分同名形参和变量

·在类的非静态成员函数中返回对象本身,可使用return *this

 代码:

#include <iostream>
using namespace std;
class people {
public:int age;people(int age) {this->age = age;}
};
void zhixing() {people p(10);cout << p.age << endl;
}
int main() {zhixing();return 0;
}

返回自身时,注意要返回引用类型,返回普通值类型时,返回值是本身的副本

#include <iostream>
using namespace std;
class people {
public:int age;people(int age) {this->age = age;}people& add(const people& p) {this->age += p.age;return *this;}
};
void zhixing() {people p1(10);people p2(20);p2.add(p1).add(p1).add(p1).add(p1);cout << p2.age << endl;
}
int main() {zhixing();return 0;
}

四.空指针访问成员函数

C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针

代码: 

#include <iostream>
using namespace std;
class person {
public:int age;void fun1() {cout << "fun1调用" << endl;}void fun2() {cout << "fun2调用" << age << endl;}};
void diaoyong() {person* p = NULL;p->fun1();p->age = 10;p->fun2();
}
int main() {diaoyong();return 0;
}

 只能成功调用没有this指针的函数,因为此时this是空指针,含有this的调用

 代码:

#include <iostream>
using namespace std;
class person {
public:int age;void fun1() {cout << "fun1调用" << endl;}void fun2() {if (this == NULL) {return;}cout << "fun2调用" << age << endl;}};
void diaoyong() {person* p = NULL;p->fun1();p->fun2();
}
int main() {diaoyong();return 0;
}

增加代码的健壮性,判断this指针是空指针的时候,跳出函数。

 五.const修饰成员函数

 常函数:

1.成员函数后加const后我们称为这个函数为常函数。

2.常函数内不可以修改成员属性。

3.成员属性声明时加关键字mutable后,在常函数中依然可以修改。

常对象:

1.声明对象前加const称对象为常对象。

2.常对象只能调用常函数和用mutable修饰的成员变量。

 5.1常函数

this指针本质是指针常量,指针的指向是不可以修改的(person* const this),但是this指针指向地址的值是可以发生改变的。

 常函数const要加在函数参数列表后面

代码: 

#include <iostream>
using namespace std;
class person {
public:int age;void showage(int m) const{//	age = 89; //报错m = 100;cout << "age=" << age <<" m=" << m << endl;}
};
void fun() {person p;p.age = 10;p.showage(7);
}
int main() {fun();return 0;
}

 此时编译器会报错,此时age在函数内是不可改变的。但是函数传的参数,仍然是可以改变的。

#include <iostream>
using namespace std;
class person {
public:mutable int age;void showage(int m) const{   //常函数age = 89; //报错m = 100;cout << "age=" << age <<" m=" << m << endl;}
};
void fun() {person p;p.age = 10;p.showage(7);
}
int main() {fun();return 0;
}

成员属性声明时加关键字mutable后,在常函数中依然可以修改。

5.2 常对象

 代码:

#include <iostream>
using namespace std;
class person {
public:mutable int age;void showage1(int m) const{//age = 89; //报错m = 100;cout << "age=" << age <<" m=" << m << endl;}void showage2(int m)  {age = 89;m = 100;cout << "age=" << age << " m=" << m << endl;}
};
void fun() {const person p;p.age = 10;      p.showage1(7);//p.showage2(7);  报错  
}
int main() {fun();return 0;
}

常对象只能调用常函数和用mutable修饰的成员变量。普通函数和普通成员变量不能调用

 六.友元

友元关键字:friend

友元的三种实现:

1.全局函数做友元

2.类做友元

3.成员函数做友元

6.1全局函数做友元 

 代码:

#include <iostream>
using namespace std;class home {
friend void func(home& p);
public:home(string keting, string woshi, string cuosuo):keting(keting),woshi(woshi),cuosuo(cuosuo) {}string keting;
private:string woshi;
protected:string cuosuo;
};void func(home &p) {cout << p.keting << ' ' << p.woshi << ' ' << p.cuosuo << endl;
}
void fun() {home p("客厅", "卧室", "厕所");func(p);
}
int main() {fun();//cout << p.keting << ' ' << p.woshi << ' ' << p.cuosuo << endl;//保护和私有属性的不能访问return 0;
}

有元函数不是类的成员函数,但是却又权限调用类的所有成员变量

6.2类做友元 

​​#include <iostream>
using namespace std;class building {
friend class goodgay;   //声明友元类
public:building();string keting;
private:string cesuo;
protected:string woshi;
};
building::building() {keting = "客厅";cesuo = "厕所";woshi = "卧室";
}class goodgay {
public:goodgay();void show();
private:building* p;
};
void goodgay::show() {cout << this->p->keting << ' ' << this->p->cesuo << ' ' << this->p->woshi << endl;
}
goodgay::goodgay() {p = new building;
}
void f() {goodgay a;a.show();
}
int main() {f();return 0;
}

 类做友元,类中的所有成员函数都能访问友元类中所有成员。

 6.3成员函数做友元

 代码:

#include <iostream>
using namespace std;
class building;
class goodgay {
public:goodgay();void show1(building& p);
private:building* p;
};class building {
friend void goodgay::show1(building& p);   //声明友元类
public:building();string keting;
private:string cesuo;
protected:string woshi;
};
building::building() {keting = "客厅";cesuo = "厕所";woshi = "卧室";
}void goodgay::show1(building& p1) {cout <<p1.keting << ' ' << p1.cesuo << ' ' << p1.woshi << endl;
}
//void goodgay::show2() {
//	cout << this->p->ketipng << ' ' << this->p->cesuo << ' ' << this->p->woshi << endl;
//}
//无权限
goodgay::goodgay() {p = new building;
}
void f() {goodgay a;building b;a.show1(b);
}
int main() {f();return 0;
}

注意类要先声明一下,防止报错,与全局函数做友元不同的是,要加上作用域。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac版本破解Typora,解决Mac安装软件的“已损坏,无法打开。 您应该将它移到废纸篓”问题

一、修改配置文件 首先去官网选择mac版本下载安装 typora下载 然后打开typora包内容找到 /Applications/Typora.app/Contents/Resources/TypeMark/ 编辑器打开上面文件夹&#xff0c;这里我拉到vscode 找到page-dist/static/js/Licen..如下图 输入 hasActivated"…

周易算卦流程c++实现

代码 #include<iostream> using namespace std; #include<vector> #include<cstdlib> #include<ctime> #include<Windows.h>int huaYiXiangLiang(int all, int& left) {Sleep(3000);srand(time(0));left rand() % all 1;while (true) {if…

Dell 服务器远程安装操作系统

登录Dell服务器管理页面 1、网络连接服务器的idrac的管理口 2、确保本地电脑与服务器的管理口可以正常通信。通过浏览器访问服务器idrac口的ip地址。建议使用IE浏览器。 默认IP地址: 192.168.0.120 子网掩码: 255.255.255.0 默认网关: 192.168.0.1 默认用户名: …

LeetCode算法心得——和可被 K 整除的子数组(前缀和+HashMap)

大家好&#xff0c;我是晴天学长&#xff0c;同余定理的应用&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。 1) .和可被 K 整除的子数组 题目描述 给定一个整数数组 A&#xff0c;返回其中元素之和可被 K 整除的&#xff08;连续、非空&#xff0…

Linux网络基础

一.协议的概念 1.1协议的概念 什么是协议 从应用的角度出发&#xff0c;协议可理解为“规则”&#xff0c;是数据传输和数据的解释的规则。假设&#xff0c;A、B双方欲传输文件。规定: 第一次&#xff0c;传输文件名&#xff0c;接收方接收到文件名&#xff0c;应答OK给传输方…

合宙Air724UG LuatOS-Air LVGL API控件-截屏(Screenshots)

截屏&#xff08;Screenshots&#xff09; 分 享导出pdf 截屏功能&#xff0c;core版本号要>3211 示例代码 -- 创建图片控件img lvgl.img_create(lvgl.scr_act(), nil)-- 设置图片显示的图像lvgl.img_set_src(img, "/lua/test.png")-- 图片居中lvgl.obj_align(…

QT基础教学(QMainWindow)

文章目录 前言一、QMainWindow介绍二、代码示例三、QMainWindow高级用法总结 前言 之前我们都是在QWidget中来进行学习的&#xff0c;那么今天我将为大家讲解一下QMainWindow。 一、QMainWindow介绍 QMainWindow是Qt框架提供的一个重要的窗口类&#xff0c;用于创建具有标准…

c语言输出杨辉三角

#include<stdio.h> int main() {int x 0; //表示杨辉三角的的大小int y 1;printf("请输入x的值: ");scanf("%d", &x);for (int i 0; i < x; i) {for (int j 0; j < i; j) {if (j 0 || i 0) {y 1;}else {y y * (i - j 1) / j;}pri…

c#动态保留小数位数的数值格式化方法实例----从小数点后非零数字保留两位进行四舍五入

c#动态保留小数位数的数值格式化方法实例----从小数点后非零数字保留两位进行四舍五入 1、功能介绍2、代码案例3、输出结果4、封装扩展方法5、控制台调用 6、其他方法地址 1、功能介绍 1. 输入的数字是整数&#xff0c;则直接返回整数部分的字符串表示。 2. 如果输入的数字是…

SpringBoot集成Apache RocketMQ详解

文章目录 0. 前言1. Spring Boot 集成Apache RocketMQ详细步骤1.1.添加依赖1.2.配置RocketMQ1.3.创建消息生产者&#xff08;Producer&#xff09;1.4.创建消息消费者&#xff08;Consumer&#xff09; 2. 测试验证3. 常见报错4. 参考文档5. 源码地址 0. 前言 上个章节我们学习…

4G版本云音响设置教程腾讯云平台版本

文章目录 4G本云音响设置教程介绍一、申请设备三元素1.腾讯云物联网平台2.创建产品3.设置产品参数4.添加设备5.获取三元素 二、设置设备三元素1.打开MQTTConfigTools2.计算MQTT参数3.使用USB连接设备4.设置参数 三、腾讯云物联网套件协议使用说明1.推送协议信息2.topic规则说明…

JDK16特性

文章目录 一、JAVA16概述二、语法层面变化1.密封类&#xff08;第二次预览&#xff09;2.instanceof 的模式匹配3.记录类习惯4基于值的类的警告 三、API层面变化1 Vector API&#xff08;孵化器&#xff09; 四、其他变化1.启用 C14 语言功能2.从 Mercurial 迁移到 Git3.ZGC&am…

Microsoft Excel 101 简介

什么是 Microsoft Excel&#xff1f; Microsoft Excel 是一个电子表格程序&#xff0c;用于记录和分析数值数据。 将电子表格想像成构成表格的列和行的集合。 字母通常分配给列&#xff0c;数字通常分配给行。 列和行相交的点称为像元。 单元格的地址由代表列的字母和代表行的…

【C++】LeetCode 160 相交链表

今天再写一道算法题&#xff08;这两周都写算法题有点摆烂&#xff09; 题目 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1…

安防监控/视频汇聚/云存储/AI智能视频分析平台EasyCVR下级海康设备无法级联是什么原因?

安防视频监控平台/视频集中存储/云存储/磁盘阵列EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。 有用户反馈&…

[JAVAee]spring-Bean对象的执行流程与生命周期

执行流程 spring中Bean对象的执行流程大致分为四步: 启动Spring容器实例化Bean对象Bean对象注册到Spring容器中将Bean对象装配到所需的类中 ①启动Spring容器,在main方法中获取spring上下文对象并配备spring. import demo.*;import org.springframework.context.Applicati…

pt26django教程

admin 后台数据库管理 django 提供了比较完善的后台管理数据库的接口&#xff0c;可供开发过程中调用和测试使用 django 会搜集所有已注册的模型类&#xff0c;为这些模型类提拱数据管理界面&#xff0c;供开发者使用 创建后台管理帐号: [rootvm mysite2]# python3 manage.…

LeetCode 753. 破解保险箱【欧拉回路,DFS】困难

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

如何从第一性原则的原理分解数学问题

如何从第一性原则的原理分解数学问题 摘要&#xff1a;牛津大学入学考试题目展示了所有优秀数学家都使用的系统的第一原则推理&#xff0c;而GPT4仍然在这方面有困难 作者&#xff1a;Keith McNulty 我们中的许多人都熟悉直角三角形的边的规则。根据毕达哥拉斯定理&#xff0c;…

2023年墨西哥 SP/BMV IPC 研究报告

第一章 指数概况 1.1 指数基本情况 墨西哥 S&P/BMV IPC 指数衡量在墨西哥证券交易所 (Bolsa Mexicana de Valores, BMV)上市&#xff0c;规模最大、流动性最高的股票表现。提供一个覆盖墨西哥股市的广泛、具有代表性且可轻易复制的指数。根据多元化要求&#xff0c;按市值…