C++语法之类(class,struct)

本文首发于个人博客

C++中可以使用struct、class来定义一个类

struct和class的区别

  • struct的默认成员权限是public
  • class的默认成员权限是private
  • 实际开发中,用class表示类比较多
1
2
3
struct Person {
int age;
};

等价于

1
2
3
4
class Person {
public:
int age;
};

操作类

  • 对类进行操作。我们有两种方式
1
2
3
4
5
6
7
Person person;
//使用对象的点语法
person.age = 10;

Person *p = &person;
//操作指针访问
p->age = 20;

汇编分析

struct

1
2
3
4
5
6
7
8
9
struct Person {
int age;

};

int main(){
Person person;
person.age = 10; //这里打断点
}

反汇编结果如下

1
2
3
4
5
6
 pushq  %rbp
movq %rsp, %rbp
xorl %eax, %eax
-> movl $0xa, -0x8(%rbp) ; person.age = 10
popq %rbp
retq

class

1
2
3
4
5
6
7
8
9
10
class Person {
public:
int age;

};

int main(){
Person person;
person.age = 10; //这里打断点
}

反汇编结果如下

1
2
3
4
5
6
 pushq  %rbp
movq %rsp, %rbp
xorl %eax, %eax
-> movl $0xa, -0x8(%rbp) ; person.age = 10
popq %rbp
retq

可以看到无论是struct还是class。汇编代码完全一样

  • 实际开发中,用class表示类比较多

this

this是指向当前对象的指针

  • 对象在调用成员函数的时候,会自动传入当前对象的内存地址

例如

1
2
3
4
5
6
7
8
class Person {
public:
int age;

void display(){
cout << "age is " << this->age << endl;
}
};

需要注意的是:不能用this.age来访问成员变量。因为this是指针。

指针访问对象成员的本质

下面代码最后打印出来的每个成员变量值是多少?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Person {
public:
int id;
int age;
int height;

void display(){
cout << " id = " << id << " age = " << age << " height = " << height << endl;
}
};

int main(){

Person person;
person.id = 10;
person.age = 20;
person.height = 30;


Person *p = (Person *)&person.age;
//操作指针访问
p->id = 40;
p->age= 50;

person.display();
return 0;
}

第一感觉是

id = 40 age = 50 height = 30

然后用编译器运行起来的结果是

id = 10 age = 40 height = 50

原因

  • 因为指针p实际指向的是person.age的地址,但是(Person *)&person.age; 欺骗编译器是指向person。
  • 64位下person中每个成员变量都是Int类型,占用4个字节。
  • 当我们修改p->id = 40;的时候,实际上修改的是age指向的内存空间。

拓展

打印的时候不用点语法,使用指针呢?如下

1
p->display();

其结果为:其中height 的值是不确定的

id = 40 age = 50 height = 1

  • 是因为,使用指针访问的时候,传入的this就是偏移了4个字节的内存空间,打印的id实际上是age,打印的age实际上是height,打印的height实际上是其他空间的数据。