目录
1 成员变量与成员函数分开存储
2 this指针
2.1 作用1
2.1.1示例
2.2 作用2
3 空指针访问成员函数
4 const修饰成员函数
4.1示例
4.2 常对象
1 成员变量与成员函数分开存储
在C++中,类内的成员变量和成员函数分开存储
首先,对于一个空对象,占用内存空间为1
class person
{
};
void test01()
{
person p;
cout << sizeof(p) << endl;
}
因为C++编译器给每个空对象分配1个字节空间,防止不同空对象占用同一块内存空间,便于区分
只有非静态成员变量才属于类的对象上
在person类中加入一个非静态成员变量
class person
{
int m_a; // 非静态成员变量,属于类的对象上
};
void test02()
{
person p;
cout << sizeof(p) << endl;
}
再加上静态成员变量
再加上非静态成员函数
最后加上静态成员函数
总结:只有非静态成员变量才属于类的对象上
2 this指针
概念:上一节中我们知道成员变量与成员函数分开存储,每一个非静态成员函数只会产生一份函数实例,也就是多个同类型的对象共用一块代码,而如何区分究竟是哪个对象调用自己,用到this指针
this指针指向被调用的成员函数所属的对象
性质:
-
this
指针是隐含在每一个非静态成员函数内的一种指针 -
this
指针不需要定义,可以直接使用
2.1 作用1
当形参与成员变量同名时,可用this指针加以区分
2.1.1示例
我们先创建类person
和测试函数test01
,在类内创建属性m_age
,函数person
,形参age
class person
{
public:
person(int age)
{
m_age = age;
}
int m_age;
};
void test01()
{
person p(20);
cout << p.m_age << endl;
}
此时可正常输出
但是,如果我们将属性m_age
改为age
得到这个
class person
{
public:
person(int age)
{
age = age;
}
int age;
};
void test01()
{
person p(20);
cout << p.age << endl;
}
同颜色的即为同一个age
,无法正常输出
在此基础上,我们在函数内加上this指针
class person
{
public:
person(int age)
{
this->age = age; // 加上this->
}
int age;
};
可以发现3个age是同源的。此时,this
就代表p
,this->age == p.age;
2.2 作用2
在类的非静态成员函数中返回对象本身,可以用return *this;
class person
{
public:
person(int age)
{
this->age = age;
}
void personAdd(person& p) // 函数本体age加上参数P的age
{
this->age += p.age;
}
int age;
};
void test02()
{
person p1(10);
cout << p1.age << endl;
person p2(10);
cout << p2.age << endl;
}
而如果我们想要多次加和
void test02()
{
p2.personAdd(p1);
cout << p2.age << endl;
p2.personAdd(p1).personAdd(p1).personAdd(p1); // 想要多次加和
cout << p2.age << endl;
}
要先修改函数体返回值
person& personAdd(person& p) // 而且要引用
{
this->age += p.age;
return *this; // 返回对象本身
}
而如果函数体返回值不使用引用&
,则无法修改值
因为这样修改完第一次p2
后,返回的是另一个变量,并且后面第2次开始修改的都是另一个变量,再另一个变量
3 空指针访问成员函数
C++
中空指针也可以调用成员函数,不过要注意是否用到this
指针
如果遇到this
指针,加上判断,防止代码出错
class person
{
public:
void show_name()
{
cout << "Joyce" << endl;
}
void show_age()
{
cout << this->m_age << endl;
}
int m_age;
};
void test01()
{
person* p = NULL;
p->show_age(); // 非法访问
p->show_name();
}
对于这段代码,指针p为NULL
,调用show_name
函数时可以正常输出,因为她只是简单的打印特定的内容,而调用show_age
函数时将报错,因为函数内this->m_age
;调用了this
指针的m_age
,而this
指针为NULL
,造成非法访问
因此,我们在函数内部加上判断
void show_age()
{
if (this == NULL)
{
return;
}
cout << this->m_age << endl;
}
以此便可以防止代码为NULL
时出错
4 const修饰成员函数
常函数:
-
成员函数后加
const
称该函数为成员函数 -
常函数不可以修改成员属性
-
成员属性声明时加关键字
mutable
,在常函数中仍然能修改
4.1示例
接下来创建person
类与函数show_name;
class person
{
public:
void show_name()
{
this->m_a = 100; // 非 常对象,可修改
this = NULL;// this指针的指向不可修改
}
int m_a;
};
因为this
指针本质是一个指针常量,所以其指向(地址)不可修改,但其指向的值可以修改
本质:
person * const this;
不过,如果在函数后加上const
,则地址与值都不可修改
本质:
const person \*const this;
不过,如果在常函数中的属性的声明前加上mutable
,则可以修改
class person
{
public:
void show_name() const // 这里有const
{
this->m_a = 100; //可修改
}
mutable int m_a; // 加上const
};
4.2 常对象
-
声明对象前加const称该对象为常对象
-
常对象只能调用常函数
class person
{
public:
void show_name() const
{
this->m_a = 100;
}
mutable int m_a;
int m_b;
};
void test02()
{
person p;
p.m_b = 20;
}
此时test02
内可以修改m_b;
接下来在p
前加上const
使其变成常对象
void test02()
{
const person p;
p.m_b = 20; // 不可修改
p.m_a = 20; // 可修改
}
则m_b
不可修改,而m_a
由于前面加了mutable
,可以修改
同时,在person
类中我们再创建一个普通函数func
,尝试在test
函数中调用刚才的常函数和普通函数
class person
{
public:
void show_name() const // 常函数
{
this->m_a = 100;
}
void func() // 普通函数
{
;
}
mutable int m_a;
int m_b;
};
void test02()
{
const person p; // 创建常对象
p.show_name(); // 常函数
p.func(); // 普通函数
}
文章来源:https://www.toymoban.com/news/detail-406193.html
无法调用,因为常对象只能调用常函数(因为普通函数可以修改属性)文章来源地址https://www.toymoban.com/news/detail-406193.html
到了这里,关于C++对象模型与this指针的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!