做网站建设公司赚钱吗申请完域名如何建设网站
做网站建设公司赚钱吗,申请完域名如何建设网站,做企业培训的网站,网站推广的公司1. 在声明 int *p[5]; 中#xff1a;
p 的元素是 int* 类型#xff08;指向整型的指针#xff09;#xff0c;而不是 int 类型
运算符优先级#xff1a;[]#xff08;数组下标#xff09;的优先级高于 *#xff08;指针#xff09;2.引用必须在定义时初始化#xff0…1. 在声明 int *p[5]; 中p 的元素是 int* 类型指向整型的指针而不是 int 类型运算符优先级[]数组下标的优先级高于 *指针2.引用必须在定义时初始化并且一旦绑定到一个变量后就不能再绑定到其他变量。int a 10;int ref a; // ref 是 a 的引用这里的a是一个对象在类的成员函数中可以通过*this获取当前类的对象引用通过一个实例化的对象去初始化int ref 表示 ref 是一个 int 类型的引用。ref 是 a 的别名对 ref 的操作会直接作用于 a。使用场景选择指针和引用怎么选 优先用引用 函数参数传递避免拷贝且无需担心空指针 类的成员函数返回值比如operator[]避免返回指针导致的空指针风险 明确需要 “别名” 且不会更改指向的场景。 必须用指针 需要动态分配内存new/delete 需要指向空值比如链表节点的尾指针 需要更改指向比如指针遍历数组、链表 C 语言兼容场景C 语言无引用只能用指针。 五、总结核心要点回顾 引用是别名无独立内存、必须初始化、不能改指向指针是地址变量有独立内存、可空、可改指向 引用使用更安全编译期检查指针更灵活但风险高野指针 / 空指针 函数传参时引用语法更简洁无需解引用指针可处理空值场景 C 语言只有指针C 保留指针的同时增加引用是为了简化语法、提升安全性。 简单记引用是 “绑死的别名”指针是 “可移动的地址标签”—— 前者简单安全后者灵活但需谨慎关于使用new语句分配和初始化数组时不同写法的区别int* a new int[10]; 未初始化内存中是随机垃圾值 仅需要内存空间后续手动赋值 int* a new int[10](); 统一值初始化所有元素初始化为 0 需要数组全部初始化为 0 int* a new int[10]{1,2,3}; 列表初始化前 3 个元素赋值剩余为 0 需要指定部分元素初始值3.在调用函数之前需要对函数进行定义在类定义中的定义的函数都是内联函数即使没有使用 inline 说明符这么说吧程序在编译器编译的时候编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换而对于其他的函数都是在运行时候才被替代4.静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句在创建第一个对象时所有的静态数据都会被初始化为零。我们不能把静态成员的初始化放置在类的定义中但是可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化5.静态成员函数即使在类对象不存在的情况下也能被调用静态函数只要使用类名加范围解析运算符 :: 就可以访问。静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数但C类的静态成员函数不能直接访问普通成员变量和普通成员函数没有this指针。静态成员函数与普通成员函数的区别静态成员函数没有 this 指针只能访问静态成员包括静态成员变量和静态成员函数。普通成员函数有 this 指针可以访问类中的任意成员而静态成员函数没有this 指针。this 指针属于对象实例不属于类。6. struct 类型名 { ... } 变量列表; 是合法的其中类型名和变量列表都是可选的但至少要有一 个9.类的构造函数是类的一种特殊的成员函数它会在每次创建类的新对象时执行。构造函数的名称与类的名称是完全相同的并且不会返回任何类型也不会返回 void。构造函数可用于为某些成员变量设置初始值11.释放 Dog 对象时先调用 Dog 的析构函数再调用 Animal 的析构函数动态绑定C 的多态通过动态绑定实现。在运行时基类指针 animalPtr 会根据它实际指向的对象类型Dog 或 Cat调用对应的 sound() 方法13.派生类的虚函数和基类的虚函数必须保持一致的有函数名参数列表类型、数量、顺序返回类型协变返回类型除外允许返回基类指针/引用的派生类指针/引用const限定符函数后的const:14. 面向对象主要三个特性是封装、继承、多态。抽象并非主要15. 在 C中常量对象和引用不能被赋值只能被初始化16.重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明但是它们的参数列表和定义实现不相同当您调用一个重载函数或重载运算符时编译器通过把您所使用的参数类型与定义中的参数类型进行比较决定选用最合适的定义。选择最合适的重载函数或重载运算符在同一个作用域内可以声明几个功能类似的同名函数但是这些同名函数的形式参数指参数的个数、类型或者顺序必须不同。您不能仅通过返回类型的不同来重载函数static局部变量只在第一次函数调用时初始化生命周期持续到程序结束在递归调用中会保持其值指向类成员函数指针的定义void (类名::*p) (int a)静态数据成员类中声明类外初始化c11之前静态常数据成员static const int这种可以在类中初始化其余都是在类中声明构造函数的初始化列表中初始化我懂了因为静态成员只能在类外初始化而初始化列表属于初始化会分配内存空间所以静态成员不能在这完成初始化因为已经在类定义好时静态成员就已经分配好内存了但在构造函数体内属于赋值操作就可以完成对静态成员的赋值非初始化现代CC11中所有常数据成员都可以在类中初始化构造函数的空参、带参构造以及带参构造时不同的参数列表都是构造函数重载的体系看const在*的哪边const在*左边指向常量内容不可变const在*右边指针常量指针不可变const在*两边都不可变注意区分类模板和模板类。类模板实例化之后就是模板类delete用于释放单个对象delete[]用于释放数组对象[]的数量是语法固定的与数组的实际维数无关多维数组需要从内到外逐层释放但每层都用delete[]。常成员函数1.只能调用常成员函数常数据成员 2.不能修改任何成员包括常成员类作用域不包含成员函数内部的作用域函数有自己的作用域逐个分析对象创建和销毁example x(5); // 对象1xexample arr[2]{1,2}; // 对象2和3arr[0], arr[1]// 这里用1和2隐式构造两个对象x10; // 临时对象4example(10)赋值后立即销毁// (先创建临时对象再赋值给x然后销毁临时对象)xexample(15); // 临时对象5example(15)赋值后立即销毁// (显式创建临时对象赋值后销毁)程序结束前存活的对象即main函数结束前xarr[0]arr[1]最后一个临时对象 example(15) 还未销毁表达式结束才销毁关键点x10; 会创建临时对象 example(10)但它在赋值表达式结束后立即销毁xexample(15); 创建临时对象 example(15)它在整个语句结束分号后才销毁因此在程序结束前main函数末尾临时对象 example(15) 还在存活期总计3个命名对象 1个临时对象 4个对象运算符重载不可以改变语法结构语法结构包括操作数个数、优先级、结合性这些都不能改变只能改变运算符在特定类型上的具体实现cin str 使用空格作为输入分隔符。输入Microsoft Visual Studio 6.0!cin str 遇到第一个空格就停止读取所以只读取到第一个空格前的内容Microsoftstr 的内容是 Microsoft剩下的 Visual Studio 6.0! 留在输入缓冲区中当使用ifstream 流类定义一个流对象并打开一个磁盘文件时文件的隐含打开方式 为ios::in19.前置 a返回自增后的 a 自身 → 可以返回引用 T后置 a必须创建一个临时对象保存自增前的值 → 只能返回值 T20. 记住就行前置是一元、后置是二元21.派生类只有实现纯虚才是抽象类。 且抽象类是无法实例化的23. 一个派生类继承了所有的基类方法但下列情况除外基类的构造函数、析构函数和拷贝构造函数。基类的赋值运算符。基类的友元函数。24.菱形继承我们发现类 GrandSon 中存在两份基类 GrandParent 的数据分别存在于类 Father 和类 Mother 中如果数据多则严重浪费空间也不利于维护。同时如果要访问基类 GrandParent 中的数据还需要通过域运算符::进行区分。虚继承为了解决上述菱形继承带来的问题C中引入了虚基类其作用是在间接继承共同基类时只保留一份基类成员。虚基类并不是在声明基类时声明的而是在声明派生类时指定继承方式virtual声明的对于虚基类的初始化是由最后的派生类中负责初始化。在最后的派生类中不仅要对直接基类进行初始化还要负责对虚基类初始化程序运行时只有最后的派生类执行对基类的构造函数调用而忽略其他派生类对虚基类的构造函数调用。从而避免对基类数据成员重复初始化。因此虚基类只会构造一次设置虚基类的目的是消除二义性当基类和派生类出现同名函数时有virtual 实现重写没有二义性当无 virtual 时出现覆盖基类无二义性。25. 而基类的 protected 成员在派生类中是 protected对象外部不能访问。派生类的缺省继承方式是private继承26. 派生类的对象可以赋值给基类的对象但基类的对象不可以赋值给派生类的对象27.派生类不一定必须实现基类的纯虚函数如果派生类没有全部实现基类的纯虚函数那么派生类仍然是抽象类不能实例化对象28.基类声明是虚函数派生类中则也是虚函数且可不写 virtual反之不成立29.构造函数调用纯虚函数时派生类部分还未构造虚函数机制不完整调用的是本类版本未实现导致未定义行为/错误。成员函数调用纯虚函数可以因为对象已完整构造此时多态生效调用派生类实现的版本。对象 “存在” 的标志内存分配 所有成员初始化完成 对象正式存在。哪怕构造函数体里的代码还没执行此时对象也已存在比如可以在构造函数体里调用对象的成员函数30.私有继承派生类中还是可以访问基类公有成员和保护成员但对象全都不能访问对象类外部能访问基类成员则定是公有。只有 public 继承才能访问基类公有31.如果构造函数里面有char* p new char[len1];这里用new分配的是数组在析构函数里面要用delete []p删32.类的数据成员含有动态分配的指针时在写构造函数、析构函数、复制构造、运算符重载时需要注意构造函数肯定需要有参数为size表示需要分配的大小析构函数需要有delete p或delete []psize1时,还要有size0复制构造和号重载其中千万不能用strcat因为返回的是一个新对象strcat是在左操作数的内存上拼接所以需要先分配再用strncpy逐一拷贝左、右字符串到新分配的字符串然后返回33.MyString MyString::operator(const MyString s2) { MyString s3(len s2.len); strncpy(s3.p, p, len); strncpy(s3.p len, s2.p, s2.len); s3.p[s3.len] \0; return s3; }现代编译器默认开启优化return s3;触发「返回值优化RVO」/「命名返回值优化NRVO」—— 编译器直接在函数调用的目标内存比如接收返回值的变量上构造s3无拷贝、无临时对象。关闭优化 / 老旧编译器会先用s3拷贝构造生成一个「临时无名对象」再用这个临时对象初始化接收变量触发拷贝构造函数结束后销毁s3和临时无名对象34.一、返回对象类型不修改操作数运算符类型具体运算符算术运算符、-、*、/比较运算符、!、、、、自增 / 自减后置(int)、--(int)二、返回引用类型修改操作数运算符类型具体运算符复合赋值运算符、-、*、/自增 / 自减前置、--赋值运算符下标运算符非 const 版[]流插入 / 提取特殊、返回流引用核心区分返回对象仅计算新值不改动原操作数返回引用修改自身 / 目标对象支持链式调用。34.用基类指针指向的派生类对象需要手动删除这个基类指针吗还是程序结束会自动调用析构函数答1. 动态分配的对象必须手动 delete如果通过new创建派生类对象并赋值给基类指针动态内存程序结束不会自动释放必须手动deleteclass Base { public: virtual ~Base() {} // 基类析构必须virtual }; class Derived : public Base {}; // 动态分配必须手动delete Base* ptr new Derived(); delete ptr; // 必须加否则内存泄漏派生类析构不执行不加delete程序结束时操作系统会回收内存但派生类析构函数不会被调用若有动态内存会泄漏属于不良编程习惯。2. 栈上的局部对象无需手动 delete如果对象是栈上局部变量出作用域会自动析构无需手动操作void func() { Derived d; Base* ptr d; // 指向栈对象无需delete } // 函数结束d自动析构基类析构virtual则派生类析构也执行关键补充基类析构必须声明为virtual否则delete 基类指针仅调用基类析构派生类析构被跳过导致派生类的动态内存泄漏动态内存new 手动delete栈内存 自动析构和 “基类指针指向派生类” 无关只和对象的分配方式有关。总结动态分配new的对象必须手动delete基类指针且基类析构需virtual栈上局部对象无需手动 delete出作用域自动析构35.抽象类的派生类并非一定要给出纯虚函数的实现,如果派生类没有给出纯虚函数的实现,这个派生类仍然是一个抽象类。36.在C语言中,能否声明虚构造函数?为什么?答虚函数作为运行过程中多态的基础,主要是针对对象的,而构造函数是在对象产生之前运行的,因此虚构造函数是没有意义的;37.virtual 、override关键字该写在派生类虚函数的声明处还是实现处 ——必须写在类内的函数声明处类外实现时绝对不能写这是 C 语法的强制要求,编译期检查38.Shape* p[2]; p[0] new Rectangle(3,4); p[1] new Circle(1.0); p[0]-getArea(); p[0]-getPerim(); p[1]-getArea(); p[1]-getPerim(); delete p[0]; // 释放指针指向的堆区new分配的对象内存会自动调用派生类析构再调用基类析构需要声明基类析构函数为虚函数 delete p[1]; // 程序到这结束 不需要手动delete []p; 数组p位于mian函数栈上