4、C++中初始化有两种方法:一种是直接初始化,如int val(1024);另一种是复制初始化,如int val=1024.
5、extern关键字表示声明变量而不是定义变量。只有当extern声明位于函数外部时,才可以含有初始化式。
6、局部变量可以屏蔽全局变量,而不是平常认为的重复定义,只有在同一个作用域中的同名定义变量才会被编译器认为是重复定义。
7、非const变量定义在全局作用域中,如果做了合适的声明,就可以在另外的文件中使用。即,在全局作用域定义非const变量时,它可以在整个程序中访问,方法是在一个文件中定义,在另一个文件中用extern声明即可。而全局的const变量是定义该对象的文件的局部变量,中存在于那个文件中。不能被其他文件访问,若指定其为extern就可以全部访问了。这个在C++ primer中我感觉是一句废话。其根源是非const变量默认是extern的。const类型在定义时必须初始化。
8、引用必须用与该引用同类型的对象初始化。const引用时指向const对象的引用。非const引用只能绑定到与该引用同类型的对象;const引用则可以绑定到不同但相关的类型的对象或绑定到右值。如:
double dval=3.14;
const int &ri=dval;
编译器会默认将其转换为:
int temp=dval;
const int &ri=temp;
9、若ri为非const,则修改ri只是改变了temp,而为改变dval.所以仅允许const引用绑定到需要临时使用的值是完全必要的。头文件中可以定义类,值在编译时就可以知道的const对象和inline函数。当const对象是由常量表达式初始化时,要放在头文件中;相反,要放在源文件中,并在其它文件中添加extern.
标准库类型
1、迭代器iterator中,vector对象ivec.end(); 返回的是末端元素的下一个地址。
2、使用const_iterator类型时,我们可以得到一个迭代器,它自身的值可以改变,但不能用来修改其指向的元素的值,可以对迭代器进行自增一级使用解引用来读取值,但不能对该元素进行赋值。
3、const iterator只能用它来改写指向的元素,不能使它指向其他元素,且必须进行初始化。
4、任何改变vector长度的操作都会使已存在的迭代器失效。
数组和指针
1、在函数体外定义的数组,其元素均初始化为0;在函数体内定义的内置类型的数组,其元素无初始化。不管数组定义在哪里,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化。数组是不允许直接复制和赋值的。
2、指针和引用的区别:①引用总是指向某个对象,定义引用时没有初始化是错误的。②给引用赋值时改变的是引用所关联的对象的值,而不是使引用与另一个对象关联。
3、不允许一个非const对象指针指向一个const对象。允许吧非const对象地址赋值给一个指向const对象的指针。
4、指向const对象的指针: const int p;.const 指针:int const p; //定义时必须初始化
5、释放动态申请的数组时要用delete[] p;不能只是delete p;这样会造成内存泄露。
6、typedef:
typedef String pstring;
const pstring cstr;==String const pstring;
因为const形容的是cstr,所以要放在它们中间。
表达式
1、求模的操作数只能为整数类型,如bool,char,short,int,long.如果两个数都是负数,求模的结果为负数或者零,如果一正一负,则结果视机器或编译器而定。
2、在一个表达式里,不要在两个或更多的子表达式中对同一个对象做自增或自减操作。这样的行为时未定义的。
3、对于包含signed和unsigned型的表达式,signed型会被转换为unsigned型。
4、如果逗号操作符最右边的操作数是左值,则逗号表达式的值也是左值。
函数
1、指针形参:若函数的形参是指向非const类型的指针,则传递的实参只能是指向非const类型的指针;若函数形参是指向const类型的指针,则传递指向const和非const类型的指针都可以。原因是:可以将指向const对象的指针初始化为指向非const对象,但不可以让指向非const对象的指针指向const对象。
2、引用形参:如果函数有非const引用形参,则不能通过const对象进行调用。
3、在调用函数时,如果该函数使用非引用的非const形参,则既可以给函数传递const实参,也可以给函数传递非const的实参。原因是在C语言中,具有const形参或非const形参并无区别,都是实参的副本,这里主要是与C语言兼容。原因:实参传递时复制传递,可以用const对象初始化非const对象,反之亦然。
4、通过引用传递数组,编译器会检查数组实参大小与形参大小是否匹配。若直接传递数组,编译器只是传递了指向数组第一个元素的指针,并不进行数组大小的匹配。如:
void func(int (&arr)[10]);
传递多维数组方法:
void func(int (arr)[10]);
//或者
void func(int arr[][10]);
5、如果一个函数的形参具有默认实参,那么,它后面所有的形参都必须具有默认实参。要给一个带默认实参的形参提供实参,那么也必须给它前面的带默认实参的形参提供实参。在一个文件中,只能为一个形参指定默认实参一次,一般在声明中指定默认实参。若在定义中的形参表中指定默认实参,那么只有在包含该函数定义的源文件中调用该函数是,默认实参才有效,所以说,默认实参一般要定义在头文件中。
6、编译器隐式的将在类内定义的成员函数当做内联函数。
7、类中成员函数形参表后面的const表明this是指向const对象的指针,不能修改调用该函数的对象,这种函数叫const成员函数。
8、关于函数指针:
//①表示cmpFcn是一种指向函数的指针类型名字。
Typedef bool (cmpFcn)(const string&,const string&);
//② 函数指针不存在类型转换。
//③ 调用函数指针的方法如:
//函数声明为
bool lengthCompare(const String&,const String&);
cmpFcn pf=lengthcompare;
lengthCompare(“hi”,“bye”);//函数名直接调用
pf(“hi”,“bye”);//函数指针调用
(pf) (“hi”,“bye”);//函数解引用调用
//④函数指针型的形参:
void useBigger(bool(const String&,const String&));
void useBigger(bool()(const String&,const String&));
标准IO库
1、IO对象不可复制或赋值。由于流对象不能复制,随意不能存在vector容器中。形参或返回类型不能为流对象。必须传递或返回IO对象的指针或者引用。引用必须是非const类型的。
类
1、const成员不能改变其所操作的对象的数据成员。const必须同时出现在声明和定义中,若只在定义或者声明中出现一处,就会出现编译错误。
2、不能从const成员函数返回指向类对象的普通引用,const成员只能返回this作为一个const引用。
3、显式指定inline成员时,可以在类内声明时写inline,也可在类外写inline,但是只能二者选一。
4、因为类可以向前声明,即只是声明,如:class A;却不定义类的成员,所以该类不能创建对象。但是可以定义该类的指针或者引用。这样便可以定义一个class A{ public:A next;};类似C语言中链表所表示的结构一样。
5、使用类的方法有两种:一种为A temp;另一种为class A temp;.这是为了和C语言的结构体兼容。
6、const对象只能使用const成员。非const对象可以使用任意成员。
7、Mutable表示可变数据成员,甚至当它是const对象也是如此。将数据成员前加上mutable关键字,const成员函数就可以改变该成员变量的值了。
8、成员函数形参表和函数体处于类作用域中,这两个可以直接使用类内定义的类型或者变量。函数的返回值类型不一定在类作用域中,与形参表相比,返回值类型出现在成员函数名字前面。如果函数定义在类定义体外,则用于返回值类型的名字在类作用域之外。如果返回值类型使用类定义的类型,则必须使用完全限定名。而形参表和成员函数体都出现在成员名之后,这些都是泪的作用域中定义,所以不用限定而使用其他成员。如:
class Screen{
public:
Typedef std::string::size_type index;
Index get_cursor() const;
private:
Int cursor;
};
Inline Screen::index Screen::get_cursor()const{
return cursor;
}
9、一旦一个名字被用作类型名,该名字就不能被重复定义。构造函数不能声明为const,因为这完全没有意义,构造函数的性质就是要给数据成员进行赋值的。
10、构造函数可以用初始化列表或函数体内赋值进行初始化。但赋值并不是显式的初始化,而是构造函数执行时先对数据成员进行默认初始化,然后再赋值覆盖。从概念上讲,可以认为构造函数分为两个阶段执行:初始化阶段;普通计算阶段。计算阶段由构造函数函数体中的语句组成。不管数据成员是否在构造函数初始化列表中显式初始化,类类型的数据成员总是在初始化阶段进行初始化。初始化发生在计算阶段之前。
11、根据上述规定,可以得出:有些成员必须在构造函数初始化列表中进行初始化。对于这样的成员,在构造函数体重对它们初始化不起作用。没有默认构造函数的类类型的成员,const或者引用类型成员必须在构造函数初始化列表中进行初始化,而不能在构造函数函数体中进行赋值初始化。
12、数据成员初始化的顺序和数据成员声明的顺序一致,而不是根据构造函数的初始化列表的顺序一致。
13、只要定义一个对象时没用提供初始化式,就使用了该类的默认构造函数。如:A a;使用的是默认构造函数,而A a(37);表示使用了其他构造函数。
14、只有类没有定义构造函数时,编译器才会自动生成一个默认构造函数。
15、单个实参调用的构造函数定义了从形参类型到该类类型的一个隐式转换。如:
class Sales_item{
public:
sales_item(const std::string &book=“”):isbn(book),unit(0),revenue(0.0){}
void same_isbn(Sales_item si);
};
//当使用对象调用
Sales_item item;
Item.same_isbn(“123556”);
//就会调用sales_item的单形参的构造函数实例化一个新对象,然后传给same_isbn做实参。从而实现隐式转换。若要避免隐式转换,就要在构造函数声明前加上expl//icit,explicit用于类内部的构造函数声明上,在类定义体外部不再重复。
16、友元只能出现在类定义的内部。
17、当我们在类外部定义static成员时,无需重复指定static保留字,该保留字只出现在类定义体内部声明处。static成员函数不能被声明为const,因为const就是承诺不会修改该函数所属对象的数据成员,但是static 不属于任何对象,static不能声明为虚函数。static成员可以通过作用域操作符,对象,引用或指向该类类型的对象的指针调用。
18、static成员函数没有this形参,它可以直接访问所属类的static成员,但不能直接使用非static成员。
19、当static成员在类外部定义时,static只写在类定义体内部的声明处。
20、static数据成员只能定义在类定义体外部,并且进行初始化,static只能在声明处标识。因为普通数据成员不能在类的定义体中初始化,但static成员定义时必须初始化,所以只能定义在定义体外部。
21、const static数据成员可以在类定义体内部进行初始化,但是数据成员必须在类定义体外部进行定义。只是在类内部初始化时,数据成员的定义不再指定初始值。
22、static数据成员可以做默认实参,其他数据成员不可以。
23、static数据成员的类型可以是该类成员所属的类型,如:
class Bar{
public:
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!