C++之认识类和对象
C++之面向对象(Object oriented Programming,OOP)
1.面向对象的三个特性
继承、封装、多态
2.类和对象的关系
类是对象的抽象,对象是类的具体实例。
类是不占用内存的,对象是占用内存的。
3.类的定义 -- 类中的数据默认是私有的
class 类名{ private: 私有数据成员和成员函数; public: 公用数据成员和成员函数; // constructor // destructor };
4.对象的定义
先声明类型,在定义对象
类名 对象名; // 静态定义对象,只有对象超出作用域才能自动释放,无法实现自定义释放
类名* 对象指针 = new 类名(形参列表); // 动态定义对象,可以使用delete运算符随时释放,delete之前调用析构函数
C++定义临时对象【重点】
类名(构造函数需要的参数); // 没有对象名,是一个无名对象,创建过程中调用构造函数
5.成员访问运算符
书写规范:先写public成员,后写private成员
public:
可以被任何随意访问
private:
private修饰的成员函数和数据成员,只能在本类中被访问
protected:受保护的
protected修饰的数据成员和成员函数,只能被本类访问和派生类的成员函数访问。
friendly:友元的
6.C++中struct和class的区别
结构体定义类可以用来写C++的数据结构,和类的用法完全相同基本。
1.用struct声明的类,如果对其成员不做private和public声明,系统会将其默认为public。
2.用class声明的类,如果对其成员不做private和public声明,系统会将默认为private。
struct定义类的格式 -- 为了兼容和拓展C,struct也可以定义类
struct 结构体名(类名){ private: 数据成员; publicd: 成员函数; };
struct定义对象
结构体名(类名) 对象;
结构体名(类名)* 对象指针 = new 类名(形参列表);
7.作用域运算符
用于声明函数是属于哪个类的。
useage1:定义属于类的函数(在类的定义外面使用) --- 推荐成员函数在类外定义
返回值 类名::函数名(形参列表){ 函数体; }
useage2:定义全局函数
返回值 ::函数名(形参列表){ 函数体; }
8.内置成员函数 -- C++编译器优化
C++中将类内部的不带循环等控制结构的成员函数优化为内置inline成员函数。
也就是说C++会在类内将可以优化为inline函数的函数自动隐式优化为inline函数(类外定义不会自动优化),所以想要在类内部声明inline函数,不需要使用inline关键字。
9.C++中对象的存储结构 -- C++编译器优化
C++中每个对象只存储自己的数据成员,不存储成员函数,因为成员函数都一样,所以放在特定的空间,为所有对象共享。
也就是说对象的数据成员和成员函数在逻辑上是放到对象中的,而物理实现是分开存储的。
10.C++编程习惯 -- 类声明和成员函数定义分离【重点--以后这样写】
1.将类的定义放到.h的头文件中
2.将类的实现放到.cpp的C++文件中
3.在主程序中只需要引入头文件即可使用相应的类
Student.h ---- 声明学生类
// // Created by 15796 on 7/16/2022. // #include <string> using namespace std; #ifndef C___TEST_STUDENT_H #define C___TEST_STUDENT_H class Student{ public: Student(string name,int age); void display(); private: int age; string name; }; #endif //C___TEST_STUDENT_H
Student.cpp --- 定义学生类的成员函数
// // Created by 15796 on 7/16/2022. // #include "Student.h" #include <iostream> Student::Student(string name, int age) { this->name = name; this->age = age; } void Student::display() { cout<<"name:"<<name<<endl; cout<<"age:"<<age<<endl; }
main.cpp --- 测试
#include <iostream> #include "Student.h" using namespace std; int main(int argv,char** argc) { Student* s = new Student("fenglei",12); s->display(); return 0; }
11.类库【重点】 -- 必须会制作自定义类库
实际工作中,可以将若干个功能相近的类的声明集中在一起形成类库。
类库的组成:
1.类声明头文件
2.已经编译过的成员函数的定义,他是目标文件。// 好处是不需要再编译了,可以直接链接到主程序中
类库的使用:
直接在主程序中导入要使用的头文件即可。
类库优点:
用户在使用的时候,只能看到类的定义,而无法看到类的成员函数的实现,因为实现的代码已经被编译为obj文件了 ,看不到源代码,保护了开发者的权益和提高了程序执行速度。
12.自定义类库及简单使用
1.s.h --- 写Student类的定义
2.s.cpp ---- 写Student类的成员函数的定义
3.a.cpp --- 写主程序,main函数
4.Makefile --- 写自动化脚本
5.删除s.cpp,以后使用s.o作为s.h的实现,就无法看到源代码了
s.h
#include <string> using namespace std; class Student{ public: Student(string name,int age); void display(); private: int age; string name; };
s.cpp
#include "Student.h" #include <iostream> Student::Student(string name, int age) { this->name = name; this->age = age; } void Student::display() { cout<<"name:"<<name<<endl; cout<<"age:"<<age<<endl; }
a.cpp
#include <iostream> #include "Student.h" using namespace std; int main(int argv,char** argc) { Student* s = new Student("fenglei",12); s->display(); return 0; }
Makefile
all:a clean a.i:a.cpp g++ -E -o a.i a.cpp a.s:a.i g++ -S -o a.s a.i a.o:a.s g++ -c -o a.o a.s a:a.o s.o // 将a.o s.o 链接到一起 g++ a.o s.o -o a clean: @rm -fr a.i a.s a.o s.cpp
执行步骤:
root@kali:/tmp/test# gcc -c -o s.o s.cpp ali:/tmp/test# rm -fr s.cpp root@kali:/tmp/test# make a root@kali:/tmp/test# make clean
注:之后s.o就是一个类库了,我们以后就不需要s.cpp了,以后再要使用Student类直接链接s.o库文件即可
结果:
root@kali:/tmp/test# ./a
name:fenglei
age:12