1. 成员变量和成员函数分开存储

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

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

  • 空对象占用内存空间为1
  • C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
#include<iostream>
#include<string>
using namespace std; //成员变量和成员函数是分开存储的 class Person{
int m_A; //非静态成员变量,属于类的对象上 static int m_B; //静态成员变量,不属于类的对象上 void func(){} //非静态成员函数,不属于类的对象上 static void func(){} //静态成员函数,不属于类的对象上
}; int Person::m_B = 10; void test01(){
Person p;
//空对象占用内存空间为1
//C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
//每个空对象也应该有一个独一无二的内存地址
cout << "size of p = " << sizeof(p) << endl;
} void test02(){
Person p;
cout << "size of p = " << sizeof(p) << endl;
} int main(){
test02();
return 0;
}

2. this指针概念

通过1我们知道了C++中成员变量和成员函数是分开存储的

每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码

那么问题是:这一块代码是如何区分哪个对象调用的自己呢?

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

this指针是隐含每一个非静态成员函数的一种指针

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

this指针的用途:

  • 当形参和成员变量同名时,可用this指针来区分
  • 在类的非静态成员函数中返回对象本身,可使用return *this
#include<iostream>
using namespace std; class Person{
public:
Person(int age){
//this指针指向被调用的成员函数所属的对象
this->age = age;
}
int age;
Person& PersonAddAge(Person &p){
this->age += p.age;
return *this;
}
}; //1. 解决名称冲突
void test01(){
Person p1(18);
cout << "p1的年龄为:" << p1.age << endl;
} //2. 返回对象本身用*this
void test02(){
Person p1(18);
Person p2(18);
//链式编程思想
p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
cout << "p2的年龄为:" << p2.age << endl;
} int main(){
test02();
return 0;
}

3. 空指针访问成员函数

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

如果用到this指针,需要加以判断保证代码的健壮性

#include<iostream>
using namespace std; class Person{
public:
void showClassName(){
cout << "this is Person class" << endl;
}
void showPersonAge(){
//错误原因是因为传入的指针是为NULL
if(this == NULL){
return ;
}//预防错误
cout << "age = " << m_age /*this->m_age*/ << endl;
}
int m_age;
}; void test01(){
Person * p = NULL;
p->showClassName();
p->showPersonAge();
} int main(){
test01();
return 0;
}

4. const修饰成员函数

常函数:

  • 成员函数加const后,我们称这个函数为常函数
  • 常函数内不可以修改成员属性
  • 成员属性声明时加关键字mutable后,在常函数中依然可以修改

常对象:

  • 声明对象加const称该对象为常对象
  • 常对象只能调用常函数

在成员函数后加const,修饰的是this指向,让指针指向的值也不可以修改

#include<iostream>
using namespace std; class Person{
public:
//this指针的本质是指针常量,指针的指向是不可以修改的
//const Person * const this;
//在成员函数后加const,修饰的是this指向,让指针指向的值也不可以修改
void showPerson() const {
m_b = 100;
m_a = 100;
cout << "this is Person class" << endl;
}
void func(){ }
int m_a;
mutable int m_b; //特殊变量,即使在常函数中,也可以修改这个值,加关键字mutable
}; void test01(){
Person * p = NULL;
p->showClassName();
p->showPersonAge();
} void test02(){
const Person p;
p.m_a = 100; //不可以修改
p.m_b = 100; //可以修改
p.showPerson(); //可以调用,是因为两个都不可以修改普通成员变量
p.func(); //不可以调用 } int main(){
test01();
return 0;
}

C++学习(10)—— 对象模型和this指针的更多相关文章

  1. 学习:类和对象——对象模型和this指针

    成员变量和成员函数分开存储: 在C++中,类内的成员变量和成员函数分开存储 第一点:空对象占用内存空间1个字节 第二点:只有非静态成员变量才属于类的对象上,非静态成员函数和静态成员函数和静态成员变量不 ...

  2. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 Windows Phone

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 Windows Phone         和.NET托管代码和 ...

  3. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型API范围

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型API范围         本章之前提到过. ...

  4. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型(CSOM)基础

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览  client对象模型(CSOM)基础         在SP2 ...

  5. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 介绍SP2013中远程APIs

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览  介绍SP2013中远程APIs         当SP首次開始 ...

  6. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 JavaScript

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览  JavaScript         与托管.NETclien ...

  7. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 托管代码(.NET)

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览  托管代码(.NET)         在SP2010中,微软提 ...

  8. javascript对象模型和function对象

    javascript中,函数就是对象 <html> <head> <script type="text/javascript"> functio ...

  9. Objective-C的对象模型和runtime机制

    内容列表 对象模型(结构定义,类对象.元类和实例对象的关系) 消息传递和转发机制 runtime系统功能理解 对象模型 结构定义 对象(Object): OC中基本构造单元 (building blo ...

随机推荐

  1. ES6-Generator使用与改写

    用Generator封装Symbol中的iterator方法: 注意:Generator的function后必须写* config:分别有3个txt文件,两个文件写路径,一个文件写要输出的内容 前置写 ...

  2. jquery根据选择器进行页面赋值,封装赋值方法

    可以进行文本框赋值,文本域赋值,下拉列表赋值,单选框赋值,多选框赋值, 传入对象,可以根据元素name进行比对赋值,不用每个进行单独赋值 <!DOCTYPE html> <html ...

  3. Java设计模式-Builder构造者模式

    介绍: 构造者模式,又称之为建造者模式,建造者模式,单例模式以及工厂模式都属于创建型模式1应用场景 今天学mybatis的时候,知道了SQLSessionFactory使用的是builder模式来生成 ...

  4. Isilon的WebUI上指定跨时区时间的小问题

    Isilon的WebUI的界面长这样: 假设我们在中国,也就是GMT+8的时区,我们想修改一个远在美国的Isilon cluster的时间. 你会发现,界面上用于指定时间的地方应该填写的不是下面选择的 ...

  5. java实现二维码的生成和解读

    Java利用QRCode.jar包实现二维码编码与解码   QRcode是日本人94年开发出来的.首先去QRCode的官网http://swetake.com/qrcode/java/qr_java. ...

  6. golang socket与Linux socket比较分析

    在posix标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带runtime的跨平台编程语言,Go中提供给开发者的socket API是建立在操作系统原生socket ...

  7. .net Core MongoDB用法演示

    C#驱动MongoDB的本质是将C#的操作代码转换为mongo shell,驱动的API也比较简单明了,方法名和js shell的方法名基本都保持一致,熟悉mongo shell后学习MongoDB的 ...

  8. typescript nodejs 依赖注入实现

    依赖注入通常也是我们所说的ioc模式,今天分享的是用typescript语言实现的ioc模式,这边用到的主要组件是 reflect-metadata 这个组件可以获取或者设置元数据信息,它的作用是拿到 ...

  9. Git 解决合并分支时的冲突

    参考链接:https://www.liaoxuefeng.com/wiki/896043488029600/900004111093344 创建分支时,新分支的文件内容建立在原分支的基础上,我们称这时 ...

  10. 在HTML网页中嵌入脚本的方式

    在HTML标记的事件属性中直接添加脚本 <!doctype html> <html> <head> <meta charset="utf-8&quo ...