#include
#include "Student.h"Stu::Stu() { std::cout << "执行了无参构造函数!" << std::endl; };Stu::Stu(std::string name, int age) { std::cout << "执行了有参构造函数!" << std::endl; };Stu::Stu(const Stu &s) { std::cout << "执行了拷贝构造函数!" << std::endl; };Stu::Stu(Stu &&s) { std::cout << "执行了移动构造函数!" << std::endl; };Stu &Stu::operator=(const Stu &s) { std::cout << "执行了拷贝赋值运算符函数!" << std::endl; };Stu &Stu::operator=(Stu &&s) { std::cout << "执行了移动赋值运算符函数!" << std::endl; };Stu::~Stu() { std::cout << "执行了析构函数!" << std::endl; };
1.3 test/C++类的六个特殊成员函数.cpp#include
/home/liuhao/CLionProjects/Robot_modules_cpp/cmake-build-debug/bin/class_function执行了无参构造函数!执行了有参构造函数!执行了拷贝构造函数!执行了移动构造函数!执行了无参构造函数!执行了拷贝赋值运算符函数!执行了无参构造函数!执行了移动赋值运算符函数!执行了main函数执行了析构函数!执行了析构函数!执行了析构函数!执行了析构函数!执行了析构函数!执行了析构函数!Process finished with exit code 0
------------------------------------------------ 2.六个函数的具体功能实现 2.1 test/Student.h#include
#include "Student.h"//=================================================================================Stu::Stu() { name = "s1"; age = 1; // TODO s1是空指针,虽然没有new,但是析构函数可以用delete,因为会判断是否为空 std::cout << name << " " << age << " " << "执行了无参构造函数!" << std::endl; std::cout << name << " " << age << " " << "指针指向的地址:" << point << std::endl; std::cout << name << " " << age << " " << "指针指向的地址的内容:" << "空指针没有指向,不能解引用操作" << std::endl; std::cout << name << " " << age << " " << "指针自身的地址:" << &point << std::endl; std::cout << "----------------------------------" << std::endl;};Stu::Stu(std::string name, int age, AA *p_temp) { this->name = "s2"; // 没有用name赋值,是为了显示 this->age = 2; // 没有用age赋值,是为了显示 point = new int(888); std::cout << this->name << " " << this->age << " " << "执行了有参构造函数!" << std::endl; std::cout << this->name << " " << this->age << " " << "指针指向的地址:" << point << std::endl; std::cout << this->name << " " << this->age << " " << "指针指向的地址的内容:" << *point << std::endl; std::cout << this->name << " " << this->age << " " << "指针自身的地址:" << &point << std::endl; std::cout << "----------------------------------" << std::endl; p_internal = new AA(name); // TODO 1.指向内部生成的内部对象,要在析构函数里面先释放后置空; if (p_temp == nullptr) { p_external = nullptr; } else { p_external = p_temp; // TODO 2.指向外部传递的外部对象,不用在析构函数里面管理; p_temp = nullptr; // 防止两个指针指向同一块内存 }};//=================================================================================Stu::Stu(const Stu &s) { name = "s3"; age = 3; if (s.point == nullptr) { point = nullptr; } else { //开辟新的空间 point = new int(); // 不要使用浅拷贝(存在动态成员的隐患),尽量使用深拷贝 //把原来的值,拷贝过来。 *point = *s.point; // TODO 注意s不能是空指针,比如s1 } std::cout << name << " " << age << " " << "执行了拷贝构造函数(深拷贝)!" << std::endl; std::cout << name << " " << age << " " << "指针指向的地址:" << point << std::endl; std::cout << name << " " << age << " " << "指针指向的地址的内容:" << *point << std::endl; std::cout << name << " " << age << " " << "指针自身的地址:" << &point << std::endl; std::cout << "----------------------------------" << std::endl;};//=================================================================================Stu::Stu(Stu &&s) noexcept { // noexcept表明函数或操作不会发生异常,会给编译器更大的优化空间。 name = "s4"; age = 4; // 移动赋值运算符函数,那这个s.name和s.age怎么处理的啊 if (s.point == nullptr) { point = nullptr; } else { // s的指向的地址赋值给当前对象this point = s.point; // s需要置空,断开指向,避免2个指针指向同一块空间 s.point = nullptr; } std::cout << name << " " << age << " " << "执行了移动构造函数!" << std::endl; std::cout << name << " " << age << " " << "指针指向的地址:" << point << std::endl; std::cout << name << " " << age << " " << "指针指向的地址的内容:" << *point << std::endl; std::cout << name << " " << age << " " << "指针自身的地址:" << &point << std::endl; std::cout << "----------------------------------" << std::endl;};//=================================================================================Stu &Stu::operator=(const Stu &s) { name = "s5"; age = 5; if (s.point == nullptr) { point = nullptr; } else { //开辟新的空间 point = new int(); // 不要使用浅拷贝(存在动态成员的隐患),尽量使用深拷贝 //把原来的值,拷贝过来。 *point = *s.point; // TODO 注意s不能是空指针,比如s1 } std::cout << name << " " << age << " " << "执行了拷贝赋值运算符函数!" << std::endl; std::cout << name << " " << age << " " << "指针指向的地址:" << point << std::endl; std::cout << name << " " << age << " " << "指针指向的地址的内容:" << *point << std::endl; std::cout << name << " " << age << " " << "指针自身的地址:" << &point << std::endl; std::cout << "----------------------------------" << std::endl; return *this;};//=================================================================================Stu &Stu::operator=(Stu &&s) noexcept { // noexcept表明函数或操作不会发生异常,会给编译器更大的优化空间。 name = "s6"; age = 6; // 移动赋值运算符函数,那这个s.name和s.age怎么处理的啊 if (s.point == nullptr) { point = nullptr; } else { // s的指向的地址赋值给当前对象this point = s.point; // s需要置空,断开指向,避免2个指针指向同一块空间 s.point = nullptr; } std::cout << name << " " << age << " " << "执行了移动赋值运算符函数!" << std::endl; std::cout << name << " " << age << " " << "指针指向的地址:" << point << std::endl; std::cout << name << " " << age << " " << "指针指向的地址的内容:" << *point << std::endl; std::cout << name << " " << age << " " << "指针自身的地址:" << &point << std::endl; std::cout << "----------------------------------" << std::endl; return *this;};//=================================================================================Stu::~Stu() { delete point; point = nullptr; std::cout << name << " " << age << " " << "执行了析构函数!" << std::endl; delete p_internal; p_internal = nullptr;};//=================================================================================//**********************************************************************************Stu &Stu::operator&&(const Stu &s) { // 重新定义了&&运算符(DIY) name = "s9"; age = 9; if (s.point == nullptr) { point = nullptr; } else { //开辟新的空间 point = new int(); // 不要使用浅拷贝(存在动态成员的隐患),尽量使用深拷贝 //把原来的值,拷贝过来。 *point = *s.point; // TODO 注意s不能是空指针,比如s1 } std::cout << name << " " << age << " " << "执行了拷贝赋值运算符函数!" << std::endl; std::cout << name << " " << age << " " << "指针指向的地址:" << point << std::endl; std::cout << name << " " << age << " " << "指针指向的地址的内容:" << *point << std::endl; std::cout << name << " " << age << " " << "指针自身的地址:" << &point << std::endl; std::cout << "----------------------------------" << std::endl; return *this;};//**********************************************************************************
2.3 test/C++类的六个特殊成员函数.cpp#include
/home/liuhao/CLionProjects/Robot_modules_cpp/cmake-build-debug/bin/class_function外部对象 执行了无参构造函数!外部对象 指针指向的地址:0x1907c20外部对象 指针指向的地址的内容:666外部对象 指针自身的地址:0x7ffdf188c390----------------------------------s1 1 执行了无参构造函数!s1 1 指针指向的地址:0s1 1 指针指向的地址的内容:空指针没有指向,不能解引用操作s1 1 指针自身的地址:0x7ffdf188c3c8----------------------------------s2 2 执行了有参构造函数!s2 2 指针指向的地址:0x1908050s2 2 指针指向的地址的内容:888s2 2 指针自身的地址:0x7ffdf188c408----------------------------------内部对象 执行了无参构造函数!内部对象 指针指向的地址:0x19080a0内部对象 指针指向的地址的内容:666内部对象 指针自身的地址:0x1908090----------------------------------s3 3 执行了拷贝构造函数(深拷贝)!s3 3 指针指向的地址:0x19080c0s3 3 指针指向的地址的内容:888s3 3 指针自身的地址:0x7ffdf188c448----------------------------------s4 4 执行了移动构造函数!s4 4 指针指向的地址:0x19080c0s4 4 指针指向的地址的内容:888s4 4 指针自身的地址:0x7ffdf188c488----------------------------------s1 1 执行了无参构造函数!s1 1 指针指向的地址:0s1 1 指针指向的地址的内容:空指针没有指向,不能解引用操作s1 1 指针自身的地址:0x7ffdf188c4c8----------------------------------s5 5 执行了拷贝赋值运算符函数!s5 5 指针指向的地址:0x19080e0s5 5 指针指向的地址的内容:888s5 5 指针自身的地址:0x7ffdf188c4c8----------------------------------s1 1 执行了无参构造函数!s1 1 指针指向的地址:0s1 1 指针指向的地址的内容:空指针没有指向,不能解引用操作s1 1 指针自身的地址:0x7ffdf188c508----------------------------------s6 6 执行了移动赋值运算符函数!s6 6 指针指向的地址:0x19080e0s6 6 指针指向的地址的内容:888s6 6 指针自身的地址:0x7ffdf188c508----------------------------------s1 1 执行了无参构造函数!s1 1 指针指向的地址:0s1 1 指针指向的地址的内容:空指针没有指向,不能解引用操作s1 1 指针自身的地址:0x7ffdf188c548----------------------------------s9 9 执行了拷贝赋值运算符函数!s9 9 指针指向的地址:0x1908100s9 9 指针指向的地址的内容:888s9 9 指针自身的地址:0x7ffdf188c548----------------------------------s9 9 执行了拷贝赋值运算符函数!s9 9 指针指向的地址:0x1908120s9 9 指针指向的地址的内容:888s9 9 指针自身的地址:0x7ffdf188c548----------------------------------s9 9 执行了拷贝赋值运算符函数!s9 9 指针指向的地址:0x1908140s9 9 指针指向的地址的内容:888s9 9 指针自身的地址:0x7ffdf188c548----------------------------------s9 9 执行了拷贝赋值运算符函数!s9 9 指针指向的地址:0x1908160s9 9 指针指向的地址的内容:888s9 9 指针自身的地址:0x7ffdf188c548----------------------------------=======================================执行了main函数s9 9 执行了析构函数!s6 6 执行了析构函数!s5 5 执行了析构函数!s4 4 执行了析构函数!s3 3 执行了析构函数!s2 2 执行了析构函数!内部对象 执行了析构函数!s1 1 执行了析构函数!外部对象 执行了析构函数!Process finished with exit code 0