c++是一门面向对象的语言 但是又该如何理解c++ 的面向对象
首先在c 语言中 有如下结构体
struct Node { int *data; Node *next; };
在c 语言中我们定义结构体变量必须带上struct
struct Node node;
而在c++ 中我们不用带struct
Node node;
在讨论c++的对象时 我们先要了解c++ 的类
例如
class Student
struct Student
都是c++的类 可以说c 语言是在写函数,c++就是在写类
一个类的实体(书,学生,管理员) → 属性(name,age,sex,id,score)(成员属性)
↓
行为(sleep,walk,talk) (成员方法)
↓↓(实例化)
对象(占内存空间)
在类里面可以定义访问限定符
protected 保护的
public 共有的 外部可以访问
private 私有的 外部无法访问
enum Sex { MAN, WOMAN }; class Student { public: void Init(char *name,int age, Sex sex);//初始化函数 void Print();//打印 private: char _name[20]; int _age; Sex _sex; };
对于一个对象 首先要对对象的属性进行初始化 对于上述学生这个对象 存放姓名用个指针动态开辟比用数组要好
enum Sex { MAN, WOMAN }; class Student { public: Student (const char *name,int age,Sex sex);//构造函数代替初始化函数 ~Student()// 析构函数 代替释放函数做释放额外申请的内存 void Print();//打印学生信息 private: char _name[20]; int _age; Sex _sex; void resize()// 栈的2倍扩容 };
我们在堆内存进行申请时 一定要注意使用完后对内存的释放 在使用的一个对象时 对对象的初始化
因此有构造函数与析构函数 帮助我们初始化与对内存的释放
1.这两个函数是没有返回值的
2.这两个函数的名字必须和类的名称一样,其中析构函数前面添加一个~号
3.析构函数不能带参数,所有一个类只有一个析构函数(也就是说析构函数不能重载)
但是构造函数的参数可以带任意个,所以可以提供多个构造函数的重载
enum Sex { MAN, WOMAN }; class Student { public: // 用构造函数代替init做对象的初始化操作 Student(const char *name, int age, Sex sex) { _pname = new char[strlen(name) + 1]; strcpy(_pname, name); _age = age; _sex = sex; } // 用析构函数代替release做释放额外开辟的对内存资源操作 ~Student() { delete[]_pname; _pname = nullptr; } void show() // 打印学生信息 { cout << "name:" << _pname << endl; cout << "age:" << _age << endl; cout << "sex:" << (_sex == MAN ? "男" : "女") << endl; } private: char *_pname; // 指针进行字符串的动态存储 int _age; Sex _sex; }; int main() { // 1.根据Student给对象开辟内存空间 2.调用合适的构造函数 Student student("xxx", 20, MAN); student.show(); //student.release(); // 做资源释放 自动释放资源 析构函数 return 0; }
当我们在主函数中 定义 Student student1(student);
就是再定义了一个student1 的对象 此时 student1 中的_name指针也是指向了student所申请的空间 这样最大的问题是 操作student1时 先析构导致空间被释放 student 再去释放时 是一个失效指针 引起错误 这就是个浅拷贝 为了防止这种情况发生 一般在构造函数后加上深拷贝函数
Student(const Student &src) { _pname = new char[strlen(src._pname) + 1]; strcpy(_pname, src._pname); _age = src._age; _sex = src._sex; }