c++学习13 类与对象(二)c++对象模型和this指针和友元
类和对象
c++对象模型和this指针
成员变量和成员函数分开存储
在c++中类内的成员变量和成员函数分开存储
只有非静态成员变量才属于类的对象
#include<iostream>
using namespace std;class Person {};
class Demo {int m_A;//非静态成员变量属于对象上
};
class Student {//非静态成员函数void sayHello() {}
};class Work {static int a;static void sayHello() {cout << "你好呀" << endl;}
};
int Work::a = 10;
void test01() {Person p;//在c++中,为了区别不同的空对象,编译器为其赋了一个字节的存储空间cout << sizeof(p) << endl;//1Demo d;cout << sizeof(d) << endl;//4 非静态成员变量属于对象上Student s;cout << sizeof(s) << endl;//1 非静态成员函数不在对象上Work w;cout << sizeof(w) << endl;//1 静态变量不在对象上
}
int main() {test01();system("pause");return 0;
}
this指针
- this指针指向被调用的成员函数所属的对象
- this指针是隐含每一个非静态成员函数内的一种指针
- this指针不需要定义,直接调用即可
this指针的作用
当形参和成员变量相同时,可用this指针来区分
在类的非静态成员函数中返回对象本身,可以使用 return * this;
注意事项: 如果返回的只是单纯的类名,则创建的是一个新的对象,只有返回引用才是返回对象本身
#include<iostream>
using namespace std;class Person {public:int age;Person(int age) {//this指向成员变量或成员函数被调用的对象this->age = age;}//如果返回的是一个引用,则返回的是本身Person& personAddAge(Person& person) {this->age += person.age;//this指向p2的指针,而*this指向p2这个对象本体return *this;}//如果返回的是一个对象,则相当于创建了一个新的对象,而本身所变的只会自身操作函数一次,后续为新的对象再进行函数内操作Person personAddAge1(Person& person) {this->age += person.age;//this指向p2的指针,而*this指向p2这个对象本体return *this;}
};void test01() {Person p(18);cout << "p的年龄为" << p.age << endl;
}void test02() {Person p1(10);Person p2(10);Person p3(10);p2.personAddAge(p1).personAddAge(p1).personAddAge(p1);p3.personAddAge1(p1).personAddAge1(p1).personAddAge1(p1);cout << "p2的年龄为:" << p2.age << endl;//40cout << "p3的年龄为:" << p3.age << endl;//20
}
int main() {test01();//18test02();system("pause");return 0;
}
空指针访问成员函数
c++中空指针也是可以调用this指针的,但是也要注意有没有用到this指针
如果用到this指针,需要加以判断保证代码的健壮性
#include<iostream>
using namespace std;class Person {public:int m_Age;void showClass() {cout << "这是小学一年级" << endl;}void showAge() {//对this做判空处理,增强代码的健壮性,防止空指针带来的异常if (this == NULL) {return;}cout << "你的年龄" << this->m_Age << endl;}};void test01() {//创建一个空指针Person* p = NULL;p->showClass();//空指针可以调用成员函数p->showAge();//由于空指针直接调用导致程序崩溃 解决方案,在成员函数中,对this多加一层判断}int main() {test01();system("pause");return 0;
}
const修饰成员函数
常函数
- 成员函数后加上const后我们称这个函数为常函数
- 常函数内不可以修改成员属性
- 只有在成员属性声明时加上关键字mutable,才可以在常函数内进行修改
常对象
- 声明对象前加const,称声明对象为常对象
- 常对象只能调用常函数
常函数修改成员属性报错示例:
常对象修改成员属性报错示例:
常对象只能调用常函数
常函数和常对象调用示例代码:
#include<iostream>
using namespace std;
class P {public:int m_A;mutable int m_B; // mutable 修饰的成员属性可以在常函数进行修改//常函数void changeValue() const{//this->m_A = 200;m_B = 20;}void func() {}
};void test01() {P p;p.changeValue();
}
void test02() {//在对象前加上关键字const修饰,变为常对象const P p;//p.m_A = 20;p.m_B = 30;//被mutable修饰的成员属性,在常对象下也可以进行修改//p.func(); //常对象不可以调用普通的成员函数,因为普通的成员函数可以修改成员属性p.changeValue();
}
int main() {test01();test02();system("pause");return 0;
}
友元
目的
让一个函数或者一个类访问另一个类的私有成员
关键字
friend
实现
- 全局函数做友元
- 类做友元
- 成员函数做友元
1 全局函数做友元需要在对应类中声明
#include <iostream>
using namespace std;
//全局函数做友元class Building {//全局函数goodFriend()作为Building类的好朋友,可以访问Building的私有成员friend void goodFriend(Building* b);
public:Building() {m_LivingRoom = "客厅";m_BedRoom = "卧室";}
public:string m_LivingRoom;
private:string m_BedRoom;
};//全局函数
void goodFriend(Building * b) {cout << "好朋友正在访问" << b->m_LivingRoom << endl;cout << "好朋友正在访问" << b->m_BedRoom << endl; //访问私有成员
}void test01() {Building b;goodFriend(&b);
}
int main() {test01();system("pause");return 0;
}
2 类做友元也需要在对应类内部声明
#include <iostream>
using namespace std;
//类做友元class Building {//GoodFriend作为Building的友元,可以访问Building的私有成员friend class GoodFriend;
public:Building();public:string m_LivingRoom;
private:string m_BedRoom;
};class GoodFriend {public:GoodFriend();void visit(); //参观函数,用来访问Building的成员Building* b;
};//类外实现成员函数
Building::Building() {m_LivingRoom = "客厅";m_BedRoom = "卧室";
}GoodFriend::GoodFriend() {b = new Building;
}
void GoodFriend::visit() {cout << "好朋友正在访问" << b->m_LivingRoom << endl;cout << "好朋友正在访问" << b->m_BedRoom << endl;
}
void test01() {GoodFriend g;g.visit();}
int main() {test01();system("pause");return 0;
}
3 成员函数做友元
这里解释一个问题,为什么不能把Buiding写在GoodFriend上,为什么会报错。
因为在Building中声明了visit()是Building的友元,固然可以在Building前面提前声明GoodFriend类,但不能在类外声明方法,故将GoodFriend声明在Building前面,并不能获取到实际的方法,在定义方法时,编译器无法把visit()这个成员函数当作Building的友元函数,故无法访问Building类的私有成员(个人理解,如果有更好的理解欢迎评论)
#include <iostream>
using namespace std;
//成员函数做友元
class Building;
class GoodFriend {public:GoodFriend();void visit(); //参观函数,用来访问Building的成员void visit2(); //参观函数2,不能访问Building的私有成员
private:Building* b;
};
class Building {friend void GoodFriend::visit();
public:Building();public:string m_LivingRoom;
private:string m_BedRoom;
};
//类外实现成员函数
Building::Building() {m_LivingRoom = "客厅";m_BedRoom = "卧室";
}GoodFriend::GoodFriend() {b = new Building;
}
void GoodFriend::visit() {cout << "1好朋友正在访问" << b->m_LivingRoom << endl;cout << "1好朋友正在访问" << b->m_BedRoom << endl;
}
void GoodFriend::visit2() {cout << "2好朋友正在访问" << b->m_LivingRoom << endl;/*cout << "好朋友正在访问" << b->m_BedRoom << endl;*/
}
void test01() {GoodFriend g;g.visit();g.visit2();}
int main() {test01();system("pause");return 0;
}
c++学习13 类与对象(二)c++对象模型和this指针和友元相关推荐
- C++阶段03笔记02【类和对象(封装、对象的初始化和清理、对象模型和this指针、友元、运算符重载、继承、多态)】
C++| 匠心之作 从0到1入门学编程[视频+课件+笔记+源码] 目录 1.内存分区模型 2.引用 3.函数提高 4.类和对象 4.1.封装 4.1.1.封装的意义 --实例1:设计圆类 --实例2: ...
- 第三层:C++对象模型和this指针
文章目录 前情回顾 C++对象模型和this指针 类成员变量和类成员函数的储存 this指针 this指针概念 this指针用途 用途1解释 用途2解释 空指针调用成员函数 const修饰的成员变量 ...
- 类和对象- C++对象模型和this指针- 成员变量和成员函数分开存储
成员变量和成员函数分开存储 在C++中,类内的成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象上 空对象占用内存空间 class Person {};void test01() {Pers ...
- 【C++编程语言】之C++对象模型和this指针
目录 1.成员变量和成员函数分开存储 2.this指针概念 3.空指针访问成员函数 4.const修饰成员函数 1.成员变量和成员函数分开存储 在C++中,类内的成员变量和成员函数分开存储,只有非 ...
- 【C++笔记】对象模型和this指针
一.成员变量和成员函数分开存储 C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象 空对象也会占用内存 C++编译器会给每个空对象也分配一个字节空间,是为了标志此对象占内存的 ...
- C++基础知识 —— 内存分区模型、引用、函数重载、类和继承、this指针、友元、多态、文件操作
参考 黑马程序员 C++课程笔记,个人理解及整理 可以使用 在线编译c++代码 来简单验证.学习代码 目录 C++核心编程 1. 内存分区模型 1.1 程序运行前 1.2 程序运行后 1.3 ...
- 十八、可迭代对象、迭代器对象和生成器
可迭代对象.迭代器对象和生成器 一 可迭代对象 二 迭代器对象 三 迭代器优缺点 三 for循环原理 四 异常处理 4.1 什么是异常 4.2 异常操作 4.2.1 语法 4.2.2 实际操作 4.2 ...
- Kotlin学习笔记 第二章 类与对象 第十二 十三节 对象表达式与对象声明 类型别名
参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...
- python class object_【python系统学习13】类(class)与对象(object)
目录: 类(class)和实例 类 整数.字符串.浮点数等,不同的数据类型就属于不同的类. 想想看当初学数据类型,我们用type验证数据类型后打印的结果 忘了就再来看看: strs = '字符串' i ...
最新文章
- 螳螂捕蝉黄雀在后!地下黑客论坛免费远控木马被曝“后门”
- JVM内存状况查看方法和分析工具
- python面试-python面试问题集锦
- mybatis教程--延迟加载详解
- 转行学python后悔_月薪13k的我为什么要转行学Python?
- .Net应用之数据连接(少儿助学网MisDataSet.dll)原代码
- qt int转换成qstring_「QT界面编程实例」创建颜色下拉框并改变窗体颜色(调色板)...
- 【操作系统】请求调页
- python快速入门步骤_Python快速入门
- android自助终端界面源码_这些安卓源码调试技巧,不懂的程序员月薪绝对不过 30k...
- mysql怎么实现的主从复制_【mysql】mysql实现主从复制
- 优秀!Github上10个开源免费的后台控制面板你值得拥有!
- EC读书笔记系列之18:条款47、48
- 【UVA1599】Ideal Path理想路径--两种约束条件(!!双向bfs+非简单图的最短路+无向图邻接记录法)
- C++二维vector初始化
- 51单片机led灯依次点亮
- adb 静默安装_apk 静默安装
- 长沙.NET技术社区正式成立
- RabbitMQ之延迟队列
- Kubernetes(k8s)的Pod资源清单spec.containers属性详细讲解
热门文章
- 配置nginx使其支持pathinfo路径模式
- 一个大专Java程序员的自述
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(转)
- 魅k30什么时候出鸿蒙系统,红米K30什么时候上市
- Illustrator 教程:如何在 Illustrator 中修改形状?
- Xamarin 可能的替代者.NET MAUI
- 微信小游戏开发(3)
- 物理层传输格式的用法,关于TF,TFS,TFC,TFCS,TFI,TFCI
- 程序员如何准备好一次面试
- 〖编程初学者的自我修养 - 优质简历篇①〗- 知己知彼,面试官是如何分析一份简历的