当前位置: 首页 > news >正文

建设网站需要哪个软件现在百度推广有用吗

建设网站需要哪个软件,现在百度推广有用吗,下载资料免费网站,网站推广公司新锐目录 1 类的6个默认成员函数 2 构造函数 3 析构函数 3 拷贝构造函数 1 类的6个默认成员函数 class Date { public:private:}; 这是一个空类#xff0c;试问里面有什么#xff1f; 可能你会觉得奇怪#xff0c;明明是一个空类#xff0c;却问里面有什么。其实一点也不…目录 1 类的6个默认成员函数 2 构造函数 3 析构函数 3 拷贝构造函数 1 类的6个默认成员函数 class Date { public:private:}; 这是一个空类试问里面有什么 可能你会觉得奇怪明明是一个空类却问里面有什么。其实一点也不奇怪这就像文件操作章节系统默认有三个流一样标准输出流(stdout)标准输入流(stdin)标准错误流(stderr)类里面系统是有默认的函数的一共有6个默认函数。 默认函数是指用户没有显式实现系统会自己生成的函数下面依次介绍。 2 构造函数 class Date { public:void Init(int year 2020,int month 1,int day 17){_year year;_month month;_day day;}private:int _year;int _month;int _day; }; 当我们写了一个日期类之后我们想要对它进行初始化我们通常都会写一个函数叫做Init()函数用来初始化里面的成员变量这是一般写法。 那么有疑问了我们介绍的不是构造函数吗为什么会涉及到构造函数 这是因为构造函数就是专门用来作为初始化函数的至于为什么取名为构造函数呢咱也不知道咱也不敢问。 构造函数应遵行一下几个点 1 函数名和类名应相同并且没有返回值 class Date { public:Date(){_year 2020;_month 1;_day 17;}void Print(){cout _year - _month - _day endl;} private:int _year;int _month;int _day; };int main() {Date d1;d1.Print();return 0; } 里面的Date()函数就是构造函数因为没有返回值所以不用加void只有默认成员函数如果没有返回值就可以不用加上void其他函数就不可以可以用print函数试验一下。 2 类实例化的时候编译器自动调用构造函数 这里就这里结合调试 是会自动跳到构造函数的留个疑问如果我们没有显式写默认构造函数会怎么样呢 3 构造函数支持函数重载 这里就复习一下函数重载的概念函数名相同函数的参数不同包括类型不同个数不同顺序不同就构成函数重载 class Date { public:Date(){_year 2020;_month 1;_day 17;}Date(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;Date d2(2024,4,10);d1.Print();d2.Print();return 0; } 构造函数可以有多个只要支持函数重载就行并且不存在调用歧义 class Date { public:Date(){_year 2020;_month 1;_day 17;}Date(int year 1, int month 1, int day 1){_year year;_month month;_day day;} private:int _year;int _month;int _day; }; 这种代码就会存在调用歧义两个函数都构成构造函数的函数重载但是调用的时候会出现问题传参的时候如果是无参则两个函数都行就会存在调用歧义所以编译器就会报错。 使用构造函数的时候一般有无参调用和带参调用 Date d1; Date d2(2024,4,10); 两种调用方式都可以取决于带不带参数都是没有问题的。 4 如果用户没有显示调用构造函数编译器就会调用默认的构造函数一旦用户显示定义构造函数系统就不会生成默认构造函数。   class Date { public:Date(int x){_year 2020;_month 1;_day 17;}void Print(){cout _year - _month - _day endl;} private:int _year;int _month;int _day; };int main() {Date d1;d1.Print();return 0; } 这里定义了一个默认构造函数系统就不会默认生成构造函数所以这里编译器会报错说没有合适的默认构造函数主要就是因为我们已经显式定义了默认构造函数。  5 构造函数只会对自定义类型进行初始化C标准没有规定对内置类型要有所处理初始化自定义类型的时候会调用该自定义类型自己的构造函数 这个点可能有点绕我们分开来看一是没有规定对内置类型有所处理 如下 class Date { public:private:int _year;int _month;int _day; };int main() {Date d1;d1.Print();return 0; } 如上打印出来都是些随机值说明编译器对这三个内置类型没有进行处理但是不乏有些编译器会将它们初始化为0这也不用惊讶因为对内置类型没有规定要处理所以可处理可不处理取决于编译器心情咯。 那么什么是调用自定义类型的构造函数呢 class Time { public:Time(){_hour 0;_minute 0;_second 0;} private:int _hour;int _minute;int _second; }; class Date { public:void Print(){cout _year - _month - _day endl;} private:int _year;int _month;int _day;Time _t; }; 当我们进行调试的时候我们会发现编译器会自动进入到Time类的构造函数随即初始化Time类的三个内置类型为0但是如果Time类中我们没有显式定义构造函数呢 那么就会 那么Time类的内置类型的成员都会是随机值有点类似无限套娃只要我们没有显式定义构造函数就会被定义为随机值是不是看起来很鸡肋 先不着急C11的标准中为了给内置成员初始化添加了一个补丁即可以在声明的时候给上缺省值 class Date { public:void Print(){cout _year - _month - _day endl;} private:int _year 1;int _month 1;int _day 1;Time _t; }; int main() {Date d1;d1.Print();return 0; } 打印出来的时候即都是1这就补上了不给内置成员初始化的缺陷。 那么构造函数是不是很鸡肋没有用处呢 实际上并不是如下 class Stack { public:private:int* arr;int _size;int _capacity; };class MyQueue { public:private:Stack _st1;Stack _st2; };在两个栈实现队列的时候当我们调用MyQueue的时候调用到MyQueue的构造函数的时候我们不需要对队列进行初始化因为使用的是栈所以在栈里面初始化队列类里面就不需要了这个时候就不需要在Queue里面显式构造函数了。 默认构造函数有三种无参构造函数全缺省构造函数系统自动生成的默认构造函数。 总结来说就是不需要传参的构造函数就是默认构造函数而且默认构造函数只能有一个不然存在调用歧义的问题。 3 析构函数 构造函数是用来初始化的那么析构函数就是用来做类似销毁的工作的但是不是对对象本身进行销毁对象本身是局部变量局部变量进行销毁是编译器完成的析构函数是用来进行对象中的资源清理的。 析构函数应遵循如下特点函数名是类型前面加个~没有返回值没有参数 class Date { public:~Date(){_year 0;_month 0;_day 0;} private:int _year;int _month;int _day; };析构函数不能函数重载如果用户显式定义了析构函数系统就不会默认生成析构函数 当代码执行到这一步的时候系统就会开始执行析构函数的代码下一步语句就会跳转到~Date函数执行代码清理工作因为析构函数没有参数所以不支持函数重载即只能有一个析构函数。 对象的声明周期结束的时候编译器会自己调用析构函数 也就是上图了因为声明周期一结束就会自己调用析构函数如果没有显式定义析构函数的话就会调用系统自己生成的析构函数。 当我们调用系统给的析构函数的时候就会发现 内置类型并没有进行处理这就是析构函数和构造函数相同的点对于内置类型没有要求要进行处理处理自定义类型的时候会调用自定义类型自己的析构函数 class Time { public:~Time(){_hour 0;_minute 0;_second 0;} private:int _hour;int _minute;int _second;}; class Date { public:private:int _year;int _month;int _day;Time _t; };同构造函数一样。 那么总结起来也是比如碰到两个栈实现一个队列的时候就可以不用写析构函数其他情况用户都是要显式定义析构函数的。 在类中如果没有资源申请那么就可以不用写析构函数如果有资源申请那么一定要写析构函数不然就会导致内存泄露. 内存泄露是一件很恐怖的事因为它不会报错内存一点点的泄露最后程序崩溃了然后重启一下程序发现又好了如此往复就会导致用户的体验很不好 class Stack { public:Stack(int capacity 4){int* tem (int*)malloc(sizeof(int) * capacity);if (tem nullptr){perror(malloc fail!);exit(1);}arr tem;_capacity capacity;_size 0;}~Stack(){free(arr);arr nullptr;_capacity _size 0;} private:int* arr;int _size;int _capacity; }; 像这种在堆上申请了空间的就一定要写析构函数不然就会导致内存泄露。 3 拷贝构造函数 拷贝构造函数拷贝就是复制像双胞胎一样复制了许多特征拷贝构造函数就是用来复制对象的应遵行如下特点拷贝构造函数是构造函数的一个重载形式 既然是构造函数的重载形式那么拷贝构造函数的函数名也应该是类名当然也是没有返回值的。 拷贝构造函数的参数只有一个是类类型的引用如果采用传值调用就会触发无限递归程序就会崩溃 这个点的信息量有点大我们一个一个解释 第一个函数参数只有一个引用类型的参数使用的时候如下 class Date { public:Date(int year,int month,int day){_year year;_month month;_day day;}Date(Date dd){_year dd._year;_month dd._month;_day dd._day;}void Print(){cout _year - _month - _day endl;} private:int _year;int _month;int _day; };int main() {Date d1(2020, 1, 17);d1.Print();Date d2(d1);d2.Print();Date d3 d1;d3.Print();return 0; } 其中参数是Date dd的就是拷贝构造函数拷贝构造函数一共有两种拷贝方法 一是Date d2 d1二是Date d3(d1)两种方式都可以的最后打印出来的结果都是2020-1-17。 那么为什么使用传值调用就会触发无限递归呢 这是因为在传值调用的时候形参也是一个对象对象之间的赋值都会涉及到拷贝构造函数的调用我们结合以下代码 class Date { public:Date(int year,int month,int day){_year year;_month month;_day day;}Date(const Date dd){_year dd._year;_month dd._month;_day dd._day;}void Print(){cout _year - _month - _day endl;} private:int _year;int _month;int _day; }; void Func(Date pd) {cout Date pd endl; } int main() {Date d1(2020, 1, 17);Func(d1);return 0; } 当代码段执行到Func的时候语句就会先跳到拷贝构造函数赋值完了才会进入到函数Func里面这时候我们监视形参pd就会发现pd已经赋值了d1的数值。 也就是说传值调用的时候就会自动跳到拷贝函数那么如果拷贝构造函数也是传值调用的话呢就会造成拷贝构造函数的形参调用拷贝构造函数的形参一直循环往复从而导致了无限递归。 这就是为什么拷贝构造函数的参数必须是引用类型了但是我们拷贝构造的时候因为是引用类型我们不希望引用类型被修改所以常加一个const进行修饰。 如果用户没有显式定义拷贝构造函数系统会默认生成拷贝构造函数拷贝构造函数按字节序进行拷贝这种拷贝被叫做浅拷贝与之对应的是深拷贝 默认成员函数都有个特点如果用户没有显式定义函数系统都会默认生成该函数。 那么什么是浅拷贝呢对于日期类无非就是赋值我们不必太过在乎但是对于Stack这种我们就需要注意一下了先看代码 class Stack { public:Stack(int capacity 4){int* tem (int*)malloc(sizeof(int) * capacity);if (tem nullptr){perror(malloc fail!);exit(1);}arr tem;_capacity capacity;_size 0;}~Stack(){free(arr);arr nullptr;_capacity _size 0;} private:int* arr;int _size;int _capacity; }; int main() {Stack s1;Stack s2(s1);return 0; }对于Stack这种有资源申请的类我们拷贝构造之后生成解决方案的时候是成功的但是当我们 运行程序的时候就会报错 报错位置是在空指针那里那么我们可以把重心放在空指针这里既然是空指针报错是我们越界访问了吗还是说我们free了两次空指针 看这个 在拷贝构造完成之后发现s1 和 s1的arr指向的空间居然是一样的 因为拷贝构造函数内置类型是按照字节序拷贝的所以拷贝的时候就会出现两个指针指向空间是同一个的情况那么在析构函数释放空间的时候就会free掉空间两次所以会报错。 浅拷贝对应的就是深拷贝所以解决方法就是深拷贝对于这种有空间申请的类我们进行拷贝构造的时候都要深拷贝不然析构的时候就会出现问题 Stack(const Stack ss){arr (int*)malloc(sizeof(int) * ss._capacity);if (arr nullptr){perror(malloc fail!);return;}memcpy(arr, ss.arr, sizeof(int) * ss._size);_size ss._size;_capacity ss._capacity;} 深度拷贝构造无非就是两个指针指向不同的空间但是里面的数据是一样的那么拷贝数据我们就可以用到memcpy然后自己开辟一块空间给s2最后赋值相关的数据就可以了这样就不会报错了。 总结 如果是日期类的拷贝构造是没有必要进行深拷贝的用系统默认生成的拷贝构造函数就行。 拷贝构造函数报错常常因为析构函数所以一般情况下拷贝构造函数不用写的话析构函数也不用写。 如果内置成员都是自定义类型如MyQueue没有指向资源默认的拷贝构造函数就可以。 如果内部资源有申请的话如Stack类就需要用户自己显式定义拷贝构造函数防止空间多次释放。 感谢阅读
http://www.pierceye.com/news/600489/

相关文章:

  • 阿里巴巴国际站网站建设青岛网站搭建公司哪家好
  • 能看人与动物做的网站浙江企业响应式网站建设设计
  • 乌兰察布做网站公司营销策划公司有哪些职位
  • 南宁区建设银行招聘网站建设部网站申请表无法打印
  • 建一个网站怎么赚钱吗家具网站源码
  • 云优化网站建设wordpress开启icon
  • 招聘网站开发的目的与意义农特产品电商网站建设目标
  • 三水 网站建设公司企业黄页
  • 网站建设公司词辽宁阜新建设学校官方网站
  • 广州公司网站建设设计顾视频网站的建设预算
  • 商务网站规划与网页制作seo优化内容
  • 石家庄网站定做公众号开发单位
  • 做预定网站的作用网站建设需求方案文档
  • 西安网站建设高端万网总裁张向东
  • 肖鸿昌建筑网站广州网站建设设计公司信息
  • 网站建设 大公司好成都网站建设哪家售后好
  • 外贸网站模板制作微营销推广方案
  • 网站开发体系用node.js可以做网站吗
  • 一个vps建两个网站怎么弄数据库网络营销应用方式
  • 网站开发快递c 网站开发入门视频教程
  • 阿里巴巴国际站介绍深圳网站建设 猴王网络
  • 扬中网站建设哪家好五百丁简历官网
  • 素马设计顾问讲解价格短视频seo什么意思
  • 注册域名查询网站智慧团建网站登陆平台
  • 网站建设和搜索引擎优化技术有哪些
  • 网站创建的基本流程seo网站排名全选
  • 乐山网站公众号建设wordpress微电影模板
  • 天津专门做网站长春市网站制作
  • 怎样用php做网站英文网站建设580
  • 凡客登录入口网站优化垂直化好还是扁平化好