目录
1、静态成员函数和静态成员变量
1)静态成员提供了一个同类对象的共享机制,静态成员局部于类,但他不属于对象;无论创建多少给对象,这些对象都共享静态成员;
2)静态成员函数提供不依赖于类数据结构的共同操作,它没有this指针;
3)有两种方法在类外调用静态成员函数,分别是1)类名::函数,2)通过对象调用;
4)普通成员函数可以使用静态变量,但静态成员函数中不能使用普通变量;
5)类静态成员变量初始化和分配内存在类外进行,不需要加static但需要带上变量类型;
6)子类可以定义一个与父类一样的静态变量,以屏蔽父类的影响。
7)当A类包含静态成员变量时,B类继承A类并使用任何方法时,必须对A中的静态成员变量进行初始化,否则编译错误;因为静态成员变量需要独立初始化同时分配内存
2、c++构造函数的delete和default
C++11中,当类中含有不能默认初始化的成员变量时,可以禁止默认构造函数的生成,
myClass()=delete;//表示删除默认构造函数
myClass()=default;//表示默认存在构造函数
当类中含有不能默认拷贝成员变量时,可以禁止默认构造函数的生成,
myClass(const myClass&)=delete;//表示删除默认拷贝构造函数,即不能进行默认拷贝
myClass & operatir=(const myClass&)=delete;//表示删除默认拷贝构造函数,即不能进行默认拷贝
3、c++拷贝构造函数以及 浅拷贝&深拷贝
class Line {
public:
int getLength( void ); Line( int len ); // 简单的构造函数
Line( const Line &obj); // 拷贝构造函数
~Line(); // 析构函数
private:
int *ptr;
};
(1)当类对象作为函数的参数时,会调用拷贝构造函数
display(line1); //作为参数传入到函数内
(2)当用一个类对象去初始化另一个类的时候,也会调用拷贝构造函数
Line line2 = line1; // 这里也调用了拷贝构造函数
(3)函数的返回值为类的对象的时候
深拷贝和浅拷贝:
深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后,两个对象虽然存的值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉。
浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间.
浅拷贝只是对对象的简单拷贝,让几个对象共用一片内存,当内存销毁的时候,指向这片内存的几个指针需要重新定义才可以使用,要不然会成为野指针,造成内存泄露。
浅拷贝:也就是在对象复制时,只是对对象中的数据成员进行简单的赋值,如果对象中存在动态成员,即指针,浅拷贝就会出现问题。
深拷贝:对于深拷贝,针对成员变量存在指针的情况,不仅仅是简单的指针赋值,而是重新分配内存空间。
class Cat{
int a;
int *ptr;
Cat(){ a = 10; ptr = new int; *ptr = 12; }
Cat(const Cat & obj){ a = obj.a; ptr = new int; *ptr = *obj.ptr; } //深拷贝为指针重新申请内存
~Cat(){ cout<<"释放内存"<<endl;}
};
4、Lambda表达式
C++11的一大亮点就是引入了Lambda表达式。利用Lambda表达式,可以方便的定义和创建匿名函数。
[capture list] (params list) mutable exception-> return type { function body }
各项具体含义如下
1)capture list:捕获外部变量列表
2)params list:形参列表
3)mutable指示符:用来说用是否可以修改捕获的变量
4)exception:异常设定
5)return type:返回类型
6)function body:函数体
示例1 sort(lbvec.begin(), lbvec.end(), [](int a, int b) -> bool { return a < b; }); // Lambda表达式 示例2 int a = 123; auto f = [a] { cout << a << endl; }; f(); // 捕获对对象a,输出:123
5.常对象和常成员函数
(1)有 const 修饰的成员函数(指 const 放在函数参数表的后面,而不是在函数前面或者参数表内),只能读取数据成员,不能改变数据成员;没有 const 修饰的成员函数,对数据成员则是可读可写的。const修饰类的成员函数,一般放在函数体后,如 void fun() const; 成员函数后加const修饰,是为了保证对象的值不被修改;函数返回值加const修饰,是为了保证其不能为左值,也就是修改的值;
(2)常量(即 const)对象可以调用 const 成员函数,而不能调用非const修饰的函数。
6.push和push_back的方法
push与push_back是STL中常见的方法,都是向数据结构中添加元素。
push和pop适合 栈和队列 stack, queue, deque;
push_back和pop_back使用 vector,map;
7.vector的初始化方法
(1) vector<int> ilist1; 这种初始化后并没有分配内存空间;
(2)vector<int> ilist2(ilist),等价为 vector<int> ilist2 = ilist;
(3)vector<int> ilist = {1,2,3.0,4,5,6,7};
(4)vector<int> ilist3(ilist.begin()+2,ilist.end()-1);
(5)vector<int> ilist4(7);ilist4中将包含7个元素,每个元素进行缺省的值初始化
(6)vector<int> ilist5(7,3);
(7)二维vector变量的初始化 vector<vector<int>> table( size1, vector<int>(size2, 0) ;
8.字符串初始化
string s1 = "abcdfddefg"; //初始化方式1
string s2("abcdfdfdefg"); //初始化方式2
string s3 = s2; //通过拷贝构造函数 初始化s3
string s4(4,'s'); //初始化7个s的字符串
9.关键字explicit
主要是为了防止隐式的转换,比如类A的构造函数参数类型为a,当有语句 A=a的时候,会调用隐式构造函数,从而是理化一个对象。加上关键字explicit则可以避免这种类型的转换,只能显示调用
10.static静态函数
使用static用于函数定义时,对函数的连接方式产生影响,使得函数只在本文件内部有效,对其他文件是不可见的。这样的函数又叫作静态函数。使用静态函数的好处是,不用担心与其他文件的同名函数产生干扰,另外也是对函数本身的一种保护机制。
如果想要其他文件可以引用本地函数,则要在函数定义时使用关键字extern,表示该函数是外部函数,可供其他文件调用。另外在要引用别的文件中定义的外部函数的文件中,使用extern声明要用的外部函数即可。