C++学习日记---第16天
笔记复习
1.C++对象模型
在C++中,类内的成员变量和成员函数分开存储
我们知道,C++中的成员变量和成员函数均可分为两种,一种是普通的,一种是静态的,对于静态成员变量和静态成员函数,我们知道他们不属于类的对象,事实上,非静态成员函数也即普通的成员函数也不属于类的对象。只有非静态成员变量也即普通的成员变量才属于类的对象。
下面是代码示例的完整代码:
#include<iostream>
using namespace std;
class person {
int m_A;
static int m_B;
void func() {
}
static void func1() {}
};
void test01() {
person p;
cout << "size of p=" << sizeof(p) << endl;
}
void test02() {
person p;
cout << "size of p=" << sizeof(p) << endl;
}
int main() {
test01();
test02();
system("pause");
return 0;
}
在C++中,空对象的内存空间为一个字节,这是由C++编译器分配的,目的是为了区分空对象占内存的位置,这样每个对象都会有独一无二的内存地址,当我们删除person类中的代码运行程序后将会输出两个1
#include<iostream>
using namespace std;
class person {
};
void test01() {
person p;
cout << "size of p=" << sizeof(p) << endl;
}
void test02() {
person p;
cout << "size of p=" << sizeof(p) << endl;
}
int main() {
test01();
test02();
system("pause");
return 0;
}
前面我们讲到只有成员变量才属于C++的对象,因此我们在空类的基础上写入成员函数,静态成员变量,静态成员函数,这个类的对象也依旧是空对象
#include<iostream>
using namespace std;
class person {
static int m_B;
void func() {
}
static void func1() {}
};
void test01() {
person p;
cout << "size of p=" << sizeof(p) << endl;
}
void test02() {
person p;
cout << "size of p=" << sizeof(p) << endl;
}
int main() {
test01();
test02();
system("pause");
return 0;
}
2.this指针
我们知道,当我们创建并调用类的对象时,这些对象会共用类中的成员函数,那么这些函数如何区分时哪个对象调用自己呢?这时候就有了this指针,C++通过提供this指针来解决该问题,。
this指针是一种特殊的指针,this指针指向被调用成员函数的所属的对象(this指向整个对象,而不只是对象里面的成员)。在非静态成员函数内部,你可以使用 this
指针访问调用对象的成员。this
实际上是当前类类型的指针,例如,对于类Kunkun的成员函数,this
是 Kunkun 类型的指针。
作用:
1)解决变量命名冲突
2)在类的非静态成员函数中返回对象本身,可使用return*this
(this指针还有更多用途,但过于复杂,这里不再介绍)
1)解决变量命名冲突
#include<iostream>
using namespace std;
class person {
public:
person(int age) {
age = age;
}
int age;
};
void test01() {
person p1(18);
p1.age = 18;
}
int main() {
test01();
return 0;
}
在这份代码种,person有参函数中的age是赋值给形参,即形参赋值给形参,并没有将接收到的形参的值赋值给成员变量,因此成员变量未初始化,当我们运行这个代码的时候就会出现成员变量未初始化的问题,这时候我们需要使用this指针
#include<iostream>
using namespace std;
class person {
public:
person(int age) {
this->age = age;
}
int age;
};
void test01() {
person p1(18);
p1.age = 18;
}
int main() {
test01();
return 0;
}
这里this指针指向被调用函数(person有参函数)所属对象(p1)的成员变量age,这样就把age区分开了,不过在实际的编程中我们会规范化命名尽量避免这种情况出现。
2)在类的非静态成员函数中返回对象本身,可使用return*this
#include<iostream>
using namespace std;
class person {
public:
person(int age) {
this->age = age;
}
person& personaddage(person &p) {
this->age += p.age;//将自身的年龄加上传入对象的年龄
return *this;
//this返回的是person类型的对象,因此函数要设置为person类型,&允许函数返回一个对象的引用而不是一个新的对象,返回对象的引用允许多个函数连续调用操作同一个对象
}
int age;
};
void test02() {
person p1(10);
person p2(10);
//链式调用:
p2.personaddage(p1).personaddage(p1).personaddage(p1);
//p2是对象,因此p2.personaddage(p1)语法正确,而如果没有return *this;
//那么返回的数据类型就是int类型,int.personaddage(p1)不成立,因此需要返回对象
cout << p2.age << endl;
}
int main() {
test02();
return 0;
}
细心的小伙伴可以发现,this指针指向一个值的时候我们修改了这个值,那么this指针能否修改指针的指向呢?答案是不能,因此this指针实际上是指针常量(指针指向的值可以改变,但指针的指向无法改变)
3.空指针访问成员函数
C++中空指针也可以访问成员函数
-
若成员函数中未使用到成员变量,可使用空指针调用该成员函数;
-
若成员函数中使用了成员变量,须对this进行判空操作,以防止程序崩溃。
对于第2点,也即C++无法用空指针来调用成员函数的成员变量
#include<iostream>
using namespace std;
class person {
public:
void showclassname() {
cout << "this is person class" << endl;
}
void showpersonage() {
if (this == NULL) {
//没有判空操作时程序会报错
return;
}
cout << "age=" << this->m_age << endl;//this指针指向p,p是一个空指针,是无法访问属性的
}
int m_age;
};
void test01() {
person* p = NULL;
p->showclassname();
p->showpersonage();
}
int main() {
test01();
system("pause");
return 0;
}