网站建设策划书范本如何做花店网站
- 作者: 五速梦信息网
- 时间: 2026年04月20日 07:54
当前位置: 首页 > news >正文
网站建设策划书范本,如何做花店网站,搜索关键词是什么意思,做网站怎么移动图片一、前言 好久没有更新内容了#xff0c;今天为大家带来类和对形中期的内容 #xff01; 二、正文 1.this指针 1.1this指针的引入 class Date { public:void Init(int year, int month, int day){_year year;_month month;_day day;}void Print(){cout _year … 一、前言 好久没有更新内容了今天为大家带来类和对形中期的内容 二、正文 1.this指针 1.1this指针的引入 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, d2;d1.Init(2023,5,12);d2.Init(2023,5,13);d1.Print();d2.Print();} 在看完上面关于“日期”这个类的定义后不知道小伙伴是否有着这样一个疑惑 Date类中有Init与Print两个成员函数函数体中没有关于不同对象的区分那么当d1调用Init函数时该函数是如何知道应该设置d1对象而不是设置d2对象呢 在C语言中当我们在实现这样的功能的时候是我们自己手动要传对象的指针给函数的而C是引入this指针来解决该问题即C编译器给每个“非静态的成员函数“增加了一个隐藏的指针参 数让该指针指向当前对象(函数运行时调用该函数的对象)在函数体中所有“成员变量”的操作都是通过该指针去访问。只不过所有的操作对用户是透明的即用户不需要来传递编译器自动完成。 1.2this指针的特性 在引入了this指针后我们就来了解下this指针到底有哪些特性呢 ①this指针的类型类类型* const即成员函数中不能给this指针赋值。 ②只能在“成员函数”的内部使用 ③this指针本质上是“成员函数”的形参当对象调用成员函数时将对象地址作为实参传递给this形参。 所以对象中不存储this指针 ④ this指针是“成员函数”第一个隐含的指针形参一般情况由编译器通过ecx寄存器自动传递不需要用户传递 //看到的 void Print() {cout _year - _month - _day endl; }//实际上[编译器自动处理] void Print(Datethis) {cout this-_year - this-_month - this-_day endl; } 2.类的六个默认成员函数 如果一个类中什么成员都没有简称为空类。 空类中真的什么都没有吗并不是任何类在什么都不写时编译器会自动生成以下6个默认成员函数。 默认成员函数用户没有显式实现编译器会生成的成员函数称为默认成员函数。 3.构造函数 3.1概念 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(2023,5,12);d1.Print();Date d2;d2.Init(2023, 5, 13);d2.Print(); } 对于Date类可以通过 Init 公有方法给对象设置日期但如果每次创建对象时都调用该方法设置信息未免有点麻烦况且有时候还可能会忘记初始化那能否在对象创建时就将信息设置进去呢因此就有了构造函数的存在。 构造函数是一个特殊的成员函数名字与类名相同,创建类类型对象时由编译器自动调用以保证每个数据成员都有一个合适的初始值并且在对象整个生命周期内只调用一次。 3.2特性 构造函数是特殊的成员函数需要注意的是构造函数虽然名称叫构造但是构造函数的主要任务并不是开空间创建对象而是初始化对象。 其特征如下 ①函数名与类名相同 ②无返回值 ③对象实例化时编译器自动调用相应的构造函数 ④构造函数可以重载 ⑤如果类中没有显式定义构造函数则C编译器会自动生成一个无参的默认构造函数一旦用户显式定义编译器将不再生成。 ⑥对于自定类型成员会调用它的默认成员函数而对于内置类型在不同的编译器下会有不同的处理方式 ⑦无参的构造函数和全缺省的构造函数都称为默认构造函数并且默认构造函数只能有一个。注意无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数都可以认为是默认构造函数。 注C11 中针对内置类型成员不初始化的缺陷又打了补丁即内置类型成员变量在类中声明时 可以给默认值。 class Time { public:Time(){cout Time() endl;_hour 0;_minute 0;_second 0;}private:int _hour;int _minute;int _second; };class Date {public://1.无参构造函数Date(){}//2.带参构造函数Date(int year, int month, int day){int _year; int _month;int _day; } private://基本类型内置类型——可以给默认值int _year2023;int _month5;int _day13;//自定义类型——编译器生成的默认构造函数会自动调用 _t的构造函数Time _t; };void TestDate() {Date d1; //调用无参构造函数Date d2(2015, 1, 1); //调用带参数的构造函数//注如果通过无参构造函数创建对象时对象后面不用跟括号否则就成了函数声明//例Date d3(); } 3.3应用场景 那么什么时候需要我们自己书写构造函数呢 一般情况下构造函数都需要我们自己写而以下两种情况下可以考虑不用写 ①内置类型成员都有缺省值且初始化符合我们的要求 ②全是自定义类型的构造且这些类型都定义了默认构造函数 4、析构函数 4.1概念 通过前面构造函数的学习我们知道一个对象是怎么来的那一个对象又是怎么没呢的 析构函数与构造函数功能相反析构函数不是完成对对象本身的销毁局部对象销毁工作是由编译器完成 的。而对象在销毁时会自动调用析构函数完成对象中资源的清理工作。 4.2特性 析构函数是特殊的成员函数其特征如下 ①析构函数名是在类名前加上字符 ~。 ②无参数无返回值类型。 ③ 一个类只能有一个析构函数。若未显式定义系统会自动生成默认的析构函数。 ④ 对象生命周期结束时C编译系统系统自动调用析构函数。 ⑤编译器生成的默认析构函数对内置类型不做处理对自定类型成员调用它的析构函数。 注意析构函数不能重载 typedef int DataType; class Stack { public:Stack(size_t capacity 3){_array (DataType)malloc(sizeof(DataType) * capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}_capacity capacity;_size 0;}void Push(DataType data){// CheckCapacity();_array[_size] data;_size;}// 其他函数…//析构函数~Stack(){if (_array){free(_array);_array NULL;_capacity 0;_size 0;}} private:DataType* _array;int _capacity;int _size; }; void TestStack() {Stack s;s.Push(1);s.Push(2); } 4.3应用场景 在了解完析构函数之后可能有的小伙伴会问那我们什么时候该自己写析构函数什么时候写析构函数呢 在一般情况下下有动态申请资源就需要写析构函数释放资源比如malloc了一块内存空间等而没有动态申请的资源或者需要释放资源的成员都是自定义类型就不需要写析构函数了 5.拷贝构造函数 5.1概念 在日常的生活中我们常常可能会见到两个一模一样的物品比如水杯足球……那么我们在创建对象的时候能不能创建一个与已存在对象一样的新对象呢答案是肯定的。 于是便有了“拷贝构造函数”对于该函数而言它只有单个形参该形参是对本类类型 对象的引用一般用const修饰在用已存在的类类型对象创建新对象时用编译器自动调用。 5.2特征 拷贝构造函数也是特殊的成员函数其特征如下 1.拷贝构造函数是构造函数的一个重载形式 2.拷贝构造函数的参数只有一个且必须是类类型对象的引用使用传值方式编译器直接报错因为会引发无穷 递归调用 //拷贝构造函数Date(const Date d){_year d._year;_month d._month;_day d._day;}//错误写法Date( Date d){_year d._year;_month d._month;_day d._day;} 我们会发现正确的拷贝构造相比于错误写法有两个不同的地方1.引用 2.const 前者是为了避免调用拷贝构造函数出现无穷递归当然编译器也会进行检查后者是为了避免我们书写时容易出现将要被拷贝的对象与拷贝对象写反导致二者的成员都为随机值的现象 3.若未显式定义编译器会生成默认的拷贝构造函数。默认的拷贝构造函数对象按内存存储按字节序完成拷贝这种拷贝叫做浅拷贝或者值拷贝 换句话来说内置类型成员完成值拷贝/浅拷贝自定义类型成员会调用它的拷贝构造函数 #include iostream using namespace std;class Date { public:Date(int year0,int month0,int day0){_year year;_month month;_day day;}拷贝构造函数//Date(const Date d)//{// _year d._year;// _month d._month;// _day d._day;//}void print(){cout _year - _month - _day endl;} private:int _year;int _month;int _day; };int main() {Date d1(2024, 1, 23);Date d2(d1);d2.print(); } 当我们将我们前文自己写过的拷贝构造函数注释掉后我们会发现结果是一样的这就是编译器自己生成的默认构造函数的效果 4.编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝那么还需要我们自己显式实现吗虽然像上面的日期类对象无需我们显式实现但是并不是所有的类都适用的比如说下面这种情况 typedef int DataType; class Stack { public:Stack(size_t capacity 10){_array (DataType*)malloc(capacity * sizeof(DataType));_size 0;_capacity capacity;}void Push(const DataType data){//checkCaapacity(); //检查容量_array[_size] data;}~Stack(){if (_array){free(_array);_capacity _size 0;}} private:DataType* _array;size_t _size;size_t _capacity; };void Text2() {Stack st1Stack(10);st1.Push(1);st1.Push(2);Stack st2(st1); }int main() {Text2(); } 对于上述对象当我不显式实现而只依赖于编译器自己生成的默认构造函数后我们会发现拷贝后的对象st2的大小容量和内容与st1都是一样的但是同时我们发现两者的成员_array的地址是一样那么当函数结束的时候st1与st2都会调用它们各自的析构函数这时候_array所指向空间就被释放了两次于是就出现了问题。 由此这也是为什么编译器能够自己生成默认的拷贝构造函数后有时候我们还需要显示实现拷贝函数。因为前者只能实现值拷贝/浅拷贝而一旦涉及内存等简简单单的拷贝就不能够满足了。这时候我们就要实现深拷贝了后面也会详细讲解 6.赋值运算符重载 6.1 运算符重载 C为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数也具有其返回值类型函数名字以及参数列表其返回值类型与参数列表与普通的函数类似。 函数名字关键字“operator”重载的运算符符号 egoperator 函数原型返回值类型 operator操作符参数列表egData operatorint day 注意 ●不能通过连接其他符号来创建新的操作符比如说operator ●重载操作符必须有一个类类型参数 ●用于内置类型的运算符。其含义不能改变例如内置的整型不能改变其含义 ●作为类成员函数重载时其形参看起来比操作数目少1因为成员函数的第一个参数为隐藏的this指针 ●“.*”, “: :”, “sizeof”, “?:” , “.”注意以上5个运算符不能重载 6.2赋值运算符重载 1.赋值运算符重载格式 ●参数类型const T 传递引用可以提高传参效率 ●返回值类型T返回引用可以提高返回的效率有返回值目的是为了支持哦连续赋值 ●检测是否自己给自己赋值 ●返回*this要复合连续赋值的含义 //赋值运算符重载Data operator(const Data d){_year d._year;_month d._month;_day d._day;return *this;} 2. 赋值运算符只能重载成类的成员函数而不能重载成全局函数 这是因为赋值运算符如果不显式实现编译器会生成一个默认的。此时用户在类外自己实现一个全局的赋值运算符重载就和编译器在类中生成的默认赋值运算符重载冲突了故赋值运算符重载只能是类的成员函数这也是默认成员函数的一个特点。 3. 由第2点我们知道当用户没有显式实现时编译器会生成一个默认赋值运算符重载以值的方式逐字节拷贝、 注内置类型成员是直接赋值的而自定义类型成员变量需要调用对应的赋值运算符重载完成赋值 class Time { public:Time(){_hour 1;_minute 1;_second 1;}Time operator(const Time t){if (this ! t){_hour t._hour;_minute t._minute;_second t._second;}return *this;} private:int _hour;int _minute;int _second; };class Date { private:// 基本类型(内置类型)int _year 2024;int _month 1;int _day 25;// 自定义类型Time _t; };int main() {Date d1;Date d2;d1 d2;return 0; } 与上面讲过的默认构造函数类似虽然编译器生成的默认赋值构造函数虽然可以完成值拷贝/浅拷贝但是对于Stack这样涉及资源管理类仅靠简单拷贝是不行的也是需要我们去实现深拷贝 6.3前置与后置重载 对于前置与后置两个函数我们知道前者是先再使用而后者是先试用再那么对于编译器而言它该如何区别呢于是我们便在传参中进行变化如果传参数便是后置无则是前置当然这是编译器的区分。在实际的使用中我们无需传参数只要像内置类型一样便可以。 Data operator(){*this 1;return *this;}Data operator(int){Data tmp (*this);(*this);return tmp;}int main(){Data d1;d1d1} 7.日期类的实现 在掌握了前面的有关类的知识后我们就可以简单的写一个类了。 下面以日期类的实现为例 typedef int DataType;class Data { public://构造函数Data(DataType year0,DataType month0,DataType day0){_year year;_month month;_day day;}//拷贝构造函数Data(const Data d){_year d._year;_month d._month;_day d._day;}//赋值运算符重载Data operator(const Data d){_year d._year;_month d._month;_day d._day;return *this;}//运算符重载bool operator(const Data d){if (_year d._year)return true;else if (_year d._year _month d._month)return true;else if (_month d._month _day d._day)return true;else return false;}//运算符重载bool operator (const Data d){if (_year d._year _month d._month _day d._day)return true;elsereturn false;}///运算符重载bool operator (const Data d){return(((*this) d) || ((*this) d));}//运算符重载bool operator (const Data d){return !(*thisd);}//运算符重载bool operator (const Data d){return !(*this d);}//获取指定年月的天数static DataType GetMonthDay(DataType year,DataType month){DataType days[13] { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//判断闰年if (month 2 ((year % 4 0 year % 100 ! 0) || (year % 400 0))){return days[2] 1;}elsereturn days[month];}//运算符重载 日期天数Data operator(DataType day){if (day 0){_day day;while (_day GetMonthDay(_year, _month)){_day - GetMonthDay(_year, _month);_month;if (_month 12){_month 1;_year 1;}}return *this;}else*this - (-day);}//运算符重载 日期天数Data operator(DataType day){Data tem(*this);tem day;return tem;}//前置运算符重载 Data operator(){*this 1;return *this;}//后置运算符重载 Data operator(int){Data tmp (*this);(*this);return tmp;}//日期的打印void print(){cout _year - _month - _day endl;}//-运算符重载 日期-天数Data operator-(DataType day){if (day 0){_day - day;while (_day 0){_month - 1;if (_month 0){_month 12;_year - 1;}_day GetMonthDay(_year, _month);}return *this;}else*this (-day);}//-运算符重载 日期-天数Data operator-(DataType day){Data tem(*this);tem - day;return tem;}//前置–运算符重载Data operator–(){*this - 1;return *this;}//-后置-运算符重载Data operator–(int){Data tmp (*this);–(*this);return tmp;}//日期-日期DataType operator-(const Data d){Data tmp this;int dis 0; //天数差值if (tmp d){while (tmp d){–(tmp);dis;}}else if(tmp d){while (tmp d){(tmp);–dis;}}return dis;}private:DataType _year;DataType _month;DataType _day;}; 8.const成员 将const修饰的“成员函数”称之为const成员函数const修饰类成员函数实际修饰该成员函数隐含的this指针表明在该成员函数中不能对类的任何成员进行修改也就是只读不写 void print() const{cout _year - _month - _day endl;} 9.取地址及const取地址操作符重载 这两个默认成员函数一般不用重新定义编译器会默认生成。 而且一般需要重载使用编译器默认取地址的重载即可只有特殊情况才需要 重载比如想让别人获取到指定的内容 class Date {public :Date operator(){return this ;}const Date* operator()const{return this ;} private :int _year ; // 年int _month ; // 月int _day ; // 日 };
- 上一篇: 网站建设策划书案例鹤壁做网站优化
- 下一篇: 网站建设策划书范文6篇台山网站设计
相关文章
-
网站建设策划书案例鹤壁做网站优化
网站建设策划书案例鹤壁做网站优化
- 技术栈
- 2026年04月20日
-
网站建设策划方案如何写网站导航页设计
网站建设策划方案如何写网站导航页设计
- 技术栈
- 2026年04月20日
-
网站建设策划范文上海网站开发平台
网站建设策划范文上海网站开发平台
- 技术栈
- 2026年04月20日
-
网站建设策划书范文6篇台山网站设计
网站建设策划书范文6篇台山网站设计
- 技术栈
- 2026年04月20日
-
网站建设策划书格式及范文温州网站关键词
网站建设策划书格式及范文温州网站关键词
- 技术栈
- 2026年04月20日
-
网站建设策划书前言网站建设初步认识的实训体会
网站建设策划书前言网站建设初步认识的实训体会
- 技术栈
- 2026年04月20日
