文章目录
- 1. 面向过程与面向对象
- 2. 类(class)
- 类的作用域
- 3. 访问限定符
- 封装
- 4. 类的实例化
- 5. this指针
1. 面向过程与面向对象
C语言是面向过程(procedure-oriented)的语言,分析出求解问题的步骤,通过函数调用逐步解决问题。以洗衣服举例,需要很多个步骤:
C++是面向对象(object-oriented)的语言,将一件事情拆分成不同的对象,靠对象之间的交互完成。洗衣服这件事可以拆分成三个对象:人、衣服和洗衣粉,可能也有洗衣机,洗衣服这个过程是由这三个或四个对象之间交互完成的。
2. 类(class)
C语言结构体中只能定义变量,在C++中结构体内不仅可以定义变量,也可以定义函数。
struct Person {char name[20];int age;char gender;int height;int weight;char introduction[100];void showInfo() {cout << name << " - " << age << " - " << gender << endl;}void sleep() {}void washCloth() {}void readBook() {}void work() {}void study() {}
};
可以这么做是因为C++需要兼容C,事实上C++更喜欢用class关键字表示一个类:
class Person
{// 类体由变量和函数组成
};
类中的变量称为类的属性或成员变量,类中的函数称为类的方法或成员函数。可以将成员的声明和定义一起放在类中,如果成员函数放在类中定义,编译器可能会将其当成内联函数处理;也可以将类成员的声明和定义分开,类中的成员变量和成员函数的声明放在.h头文件,成员函数的定义放在.cpp文件。
类的作用域
类定义了一个新的作用域,在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。
class Person {char name[20];int age;char gender;int height;int weight;char introduction[100];void showInfo();void sleep();void washCloth();void readBook();void work();void study();
};void Person::showInfo() {cout << name << " - " << age << " - " << gender << endl;
}
3. 访问限定符
访问限定符用于确定类成员的访问权限:
- public:被public修饰的成员在类外可以被访问;
- protected:被protected修饰的成员在类外不能被访问,但可以在继承的子类中被访问;
- private:被private修饰的成员在类外不能被访问。
class关键字定义类的默认访问权限是private,这是因为面向对象三大特性之一的封装。struct关键字定义类的默认访问权限是public,因为需要兼容C。
封装
面向对象的三大特性:封装、继承、多态。封装是将数据和操作数据的方法进行结合,通过访问权限来隐藏对象内部的属性和实现细节,控制哪些函数可以在类外部直接被使用,仅对外公开接口来和对象进行交互。
封装本质上是一种管理,让用户更方便使用类。比如对于电脑这样一个复杂的设备,提供给用户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互。对于计算机使用者而言,不用关心内部核心部件,主板上线路是如何布局的,CPU内部是如何设计的。
class Person {private:char name[20];int age;char gender;int height;int weight;char introduction[100];public:void showInfo();void sleep();void washCloth();void readBook();void work();void study();
};void Person::showInfo() {cout << name << " - " << age << " - " << gender << endl;
}
4. 类的实例化
用类类型创建对象的过程,称为类的实例化。类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它。一个类可以实例化出多个对象,实例化出的对象占用实际的内存空间,存储类成员变量。
int main() {Person p1;Person p2;Person p3;
}
计算对象的内存大小与计算结构体的大小一致,可以看这篇文章计算结构体的大小了解,简单地说就是按计算结构体大小的方式来计算类成员变量的大小。成员函数不会包括在内,因为成员函数是n个对象共用的,存放在公共代码区。另外空类比较特殊,它也有大小,占用1个字节空间。
5. this指针
this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给
this形参,因此this指针并不存放在对象中,而是在栈中(可能也在寄存器中,取决于编译器)。
this指针的类型:类的类型* const,只能在“成员函数”的内部使用。this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要程序员手动传递。
下面两段程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:void Print(){cout << "Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}
C.正常运行,表面存在空指针问题,但成员函数中并没有使用其它成员,仅仅只是打印一个字符串,不会导致空指针访问。
class A
{
public:void PrintA() {cout<<_a<<endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->PrintA();return 0;
}
B.运行崩溃,成员函数中使用了成员变量,实际上是this指针访问的成员,造成了空指针。