pc端网站开发,手机app开发自学教程,基于mvc4商务网站开发,十大永久免费财务软件#x1f3ac; 鸽芷咕#xff1a;个人主页 #x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想#xff0c;就是为了理想的生活! 引入 哈喽各位铁汁们好啊#xff0c;我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发#xff0c;不知道各位的… 鸽芷咕个人主页 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想就是为了理想的生活! 引入 哈喽各位铁汁们好啊我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发不知道各位的城市有没有这种实惠又全面的零食基地呢C 本身作为一门篇底层的一种语言世面的免费课程大多都没有教明白。所以本篇专栏的内容全是干货让大家从底层了解C把更多的知识由抽象到简单通俗易懂。 ⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站通俗易懂风趣幽默忍不住分享一下给大家。点击跳转到网站。 文章目录 引入⛳️ 推荐一、this指针的概念1.1 this 指针的引入1.2 this 指针的特性this 指针存在哪里this指针可以为空吗? 二、六个默认成员函数三、构造函数3.1 构造函数的概念3.2 构造函数的特性无参构造函数无参的默认构造函数 四、析构函数4.1 析构函数函数的概念4.2 析构函数的特性 文章结语 一、this指针的概念
1.1 this 指针的引入 来讲 this 之前我们先来看一下下面这段代码 这里 printf 函数我们并没有传递参数那么他如何知道我们打印的是那个对象对的呢?
#define _CRT_SECURE_NO_WARNINGS 1
#includeiostream
using namespace std;class Data
{
public:void Init(int year, int month, int day){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}private:int _year;int _month;int _day;
};int main()
{Data d1,d2;d1.Init(2023, 2, 27);d2.Init(2023, 4, 07);d1.print();return 0;
}这里我们去调用 d1.print(); 但是 print 函数并没有参数是如何知道要打印 其实在C这里虽然我们没有给print 函数参数但实际上是有一个默认的this 指针来自动调用的实际的代码可能是下面这样但是编译器给自动化了大大简化了用户操作。 C中通过引入this指针解决该问题即C编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数让该指针指向当前对象(函数运行时调用该函数的对象)在函数体中所有“成员变量”的操作都是通过该指针去访问。只不过所有的操作对用户是透明的即用户不需要来传递编译器自动完成。 1.2 this 指针的特性
this指针的类型类类型 const即成员函数中不能给this指针赋值。*只能在“成员函数”的内部使用this指针本质上是“成员函数”的形参当对象调用成员函数时将对象地址作为实参传递给this形参。所以对象中不存储this指针。this指针是“成员函数”第一个隐含的指针形参一般情况由编译器通过ecx寄存器自动传递不需要用户传递
this 指针存在哪里 this 前面我们说了 其实是我们成员函数的形参所以 this 指针其实是存放在 栈区的。有些编译比如vs可能会用寄存器存储 this指针可以为空吗?
这个问题我们就来看下下面这俩个练习题了 代码演示
// 1.下面程序编译运行结果是 A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:void Print(){cout Print() endl;}
private:int _a;
};
int main()
{A* p nullptr;p-Print();return 0;
}这个小程序相信大家都看得出来是选 C 虽然我们的 p 是一个空指针但是调用函数的时候并不会传递this 指针或者使用空指针所以程序正常运行 代码演示
// 1.下面程序编译运行结果是 A、编译报错 B、运行崩溃 C、正常运行
class A
{
public:void PrintA(){cout _a endl;}
private:int _a;
};
int main()
{A* p nullptr;p-PrintA();return 0;
}而这个程序就不可以了我们对空指针进行解引用一定对引发程序崩溃 因为我们使用了成员变量 _a 但成员变量的地址又是一个空地址 二、六个默认成员函数 如果一个类中什么成员都没有简称为空类。 空类中真的什么都没有吗并不是任何类在什么都不写时编译器会自动生成以下6个默认成员 函数。 默认成员函数用户没有显式实现编译器会生成的成员函数称为默认成员函数。 同时这六个默认成员函数也是我们面向对象的核心下面我们就来先介绍一下构造函数和析构函数 三、构造函数
3.1 构造函数的概念 构造函数咋一听名字各位是不是觉得他是用来创建函数的其实大家是被名字误导了。构造函数的实际作用就是 和 Init 函数一样用来初始化我们的对象 以往我们初始化对象都需要自己去手动调用非常麻烦单是构造函数这种默认成员函数就不需要了自动调用帮我们初始化化 class Date
{
public:void Init(int year, int month, int day){_year year;_month month;_day day;}void Print(){cout _year - _month - _day endl;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;d1.Init(2022, 7, 5);d1.Print();Date d2;d2.Init(2022, 7, 6);d2.Print();return 0;
} 这里我们每次调用日期类都要给它去初始化太麻烦了但是使用构造函数来进行初始化就方便很多 代码演示
class Date
{
public:Date(int year 2023, int month 2, int day 29){_year year;_month month;_day day;}void Print(){cout _year - _month - _day endl;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;d1.Print();Date d2(2022, 7, 6);d2.Print();return 0;
}
3.2 构造函数的特性 构造函数是一个默认成员函数也是一个非常特殊的成员函数。可以帮助我们自动初始化对象而且自动调用它有以下一个特性 函数名与类名相同。无返回值。对象实例化时编译器自动调用对应的构造函数。构造函数可以重载。
无参构造函数 有些场景下我们肯需要无参构造函数但是很多新手在调用的时候总会出现调用错误 无参构造函数在调用的时候是不需要写括号的对象后面不用跟括号否则就成了函数声明 class Date
{
public:// 1.无参构造函数Date(){}// 2.带参构造函数Date(int year, int month, int day){_year year;_month month;_day day;}
private:int _year;int _month;int _day;
};void TestDate()
{Date d1; // 调用无参构造函数Date d2(2015, 1, 1); // 调用带参的构造函数// 注意如果通过无参构造函数创建对象时对象后面不用跟括号否则就成了函数声明// 以下代码的函数声明了d3函数该函数无参返回一个日期类型的对象// warning C4930: “Date d3(void)”: 未调用原型函数(是否是有意用变量定义的?)Date d3();
}
无参的默认构造函数 如果类中没有显式定义构造函数则C编译器会自动生成一个无参的默认构造函数一旦 用户显式定义编译器将不再生成。 但是这个构造函数对内置类型不处理对自定义类型调用它的默认函数 比如说这里我们就没有去显示创建构造函数但是自动创建了一个默认构造函数默认构造函数
对自定义类型调用他的构造函数对内置类型不做处理 这里很多人就觉得为什么对内置类型不处理自动处理了不是更好吗可能是祖师爷在编写的打了个盹给搞忘了哈哈哈开个玩笑 所以在C11的时候对这里打了补丁即内置类型成员变量在类中声明时可以给默认值。 代码演示
class Date
{
public:void print(){cout _year _month _day endl;}private:int _year 2023;int _month 2;int _day 17;
};int main()
{Date a1;return 0;
}代码结果 无参的构造函数和全缺省的构造函数都称为默认构造函数并且默认构造函数只能有一个。
注意无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数都可以认为是默认构造函数
四、析构函数
4.1 析构函数函数的概念 构造函数是用来自动初始化对象的那么自动清理对象是用那个呢没错这就是析构函数该干的工作了析构函数主要负责清理空间和我们以前数据结构中的 destroy 销毁空间的作用是一样的 4.2 析构函数的特性
析构函数是特殊的成员函数其特征如下
析构函数名是在类名前加上字符 ~。无参数无返回值类型。一个类只能有一个析构函数。若未显式定义系统会自动生成默认的析构函数。注意析构函数不能重载对象生命周期结束时C编译系统系统自动调用析构函数。 代码演示
class Date
{
public:void print(){cout _year _month _day endl;}~Date(){cout time~ endl;}
private:int _year 2023;int _month 2;int _day 23;
};int main()
{Date a1;return 0;
}这里我们就可以看到了我们不取调用析构函数但是在程序结束的时候自动调用 关于编译器自动生成的析构函数是否会完成一些事情呢下面的程序我们会看到编译器 生成的默认析构函数对自定类型成员调用它的析构函数。 这里析构函数和构造函数是一模一样的对自定义类型才会去默认调用它的析构函数 class Time
{
public:~Time(){cout ~Time() endl;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本类型(内置类型)int _year 1970;int _month 1;int _day 1;// 自定义类型Time _t;
};
int main()
{Date d;return 0;
}如果类中没有申请资源时析构函数可以不写直接使用编译器生成的默认析构函数比如 Date类有资源申请时一定要写否则会造成资源泄漏比如Stack类。 因为析构函数一般是用来释放我们申请的空间而内置类型在程序结束会自动释放空间所以没有申请资源可以不写析构函数 文章结语
☁️ 看到这里了还不给博主扣个 ⛳️ 点赞收藏 ⭐️ 关注 ❤️ 拜托拜托这个真的很重要 你们的点赞就是博主更新最大的动力