百科不全书之C++

  1. 内联函数:为了避免函数开销,直接替换代码,不会产生调用函数的语句 函数头加 inline。
  2. 函数缺省参数:最右边连续若干个参数有缺省值。避免函数重载时的二义性
  3. 复制构造函数:x:x(const x&) 如果自己没写,编译器会默认构造复制函数。 起作用:用一个类初始化同类的另一个对象x c1(c2),x c1=c2,。 函数有一个参数是类的对象,调用函数,复制构造也被调用。 函数返回值是类的对象,函数的对象会用复制对象初始化。 对象间的赋值不会导致复制构造函数调用。 为了防止调用开销,可以用引用。
  4. 类型转换函数:先把数据变为零时类型在转换。deno c1=5 5变为临时对象复制给c1 explicit Test2 t2=12;//编译错误,不能隐式调用其构造函数。Test2 t2(12);//显式调用成功
  5. 析构函数:delere [] test 对象数组。只是拆房子之前,进入善后工作。构造不建房子,只装修房子。可以构造数组 test c1[3]={1,test(1,2)}; test*c1[3]={new test(4),new test(1)}; new 出来的不delete就不会消亡
  6. 定义类:struct也可以定义类,只不过未声明的为公有。
  7. 引用:T & 可以初始化 const T& 。但是const T 不能初始化 T
  8. this指针:最开始c++没有编译器,在使用类的成员函数时,就把类取地址,用this指向类的成员变量。静态成员函数不能使用this指针。
  9. 静态成员:静态的成员变量是被所有对象共享的,例如你改了类A的静态变量,类B也变。静态成员函数并不作用于某个对象,因此静态成员不需要通过对象就能访问。1.类名::成员名。 2.对象名.成员名;静态本质上是全局变量。哪怕没对象,但是也存在。sizeof的时候不算进去。使用的时候先初始化和声明。静态成员函数中,不能访问非静态成员函数和非静态成员变量。如果在构造中使用,注意复制构造函数。
  10. 封闭类:有成员对象的类叫做封闭类。CCar 汽车类 包含 CTyre(成员对象) CEngjne 两个类所以是封闭类。初始化列表 CTyre(int r,int w): radius® width(w){};注意要让编译器明白,对象中的成员对象,如何初始化。使用封闭类的构造函数的初始化列表。先调用成员对象的构造函数,然后执行封闭类的构造函数。对象成员的构造函数调用次序和对象成员在类中说明次序一致,与它们在初始化列表中次序无关。消亡时 先执行封闭类的构造函数,在执行成员对象的析构函数,次序与构造相反,先构造再析构。 封闭类的复制构造函数:封闭类的成员对象的复制构造函数会调用成员类的复制构造函数。
  11. 常量:常量成员函数 执行期间不应修改其作用的对象,不能修改成员变量的值(静态成员变量除外),也不能调用同类的非常量成员函数。void get() const; void sam::get() const 。有两个一样的函数,一个加const 一个没加,不算重载。常引用:comst a 做函数参数会调用复制构造 浪费 comst & a 就可以节约资源。用const 常引用更好
  12. 友元函数:friend,有类和函数,无传递和继承。友元其实破坏了封装性。有点C++向c妥协的意思。
  13. 运算符重载:实质为函数重载。可重载为普通函数,也可重载为成员函数。可以被多次重载。类名(参数),会生成一个临时对象 operator 成员函数重载参数个数减1,重载为全局函数,参数个数不变。 特殊:=赋值运算符重载,只能重载为成员函数。=的值是右边的引用。浅拷贝深拷贝:A=B A的每一个字节都等于B. s1=s2 s1指向s2的地址,这个时候s1原来的会生产内存垃圾,s1 delete的时候,会影响s2。s2 delete的时候,会delete同一个空间两次。a=b 等号左边为引用。
  14. 运算符重载为友元函数:c+5可以,但是5+c不行。重载为友元~
  15. 可变长数组:非引用的函数返回值,不能做左值。复制号左边本来就是等号右边的引用。
  16. 流插入提取运算符的重载:cout与《运算符,cout是iostream中定义的ostream类的对象,并且对《运算符做了重载。类型转换运算符重载时返回值不写的,返回值就是这个类型本身,作用把对象转换为类型。 自增,自减运算符的重载:前置作为一元运算符重载,返回值为引用。后置作为二元重载,并不是引用,是临时对象。++i比i++快。. * :: sizeof不能被重载, 重载 () 【】->时,必须声明为类的成员函数。
  17. 析构函数:delere [] test 对象数
  18. 继承和派生:派生类定义后,拥有基类的全部成员函数与变量。但是不能访问基类的private成员。派生类体积等于基类+派生类自己添加的。基类存储位置在派生类前面。派生类访问基类成员,要使用作用域符号::,缺省情况下,访问的是派生类的,protected 保护的。权限比public小,比private大。初始化列表学会,声明的时候可以不写初始化列表。复合关系的用指针。 派生类对象可以赋值给基类对象,反之不行。
  19. 虚函数和多态: virtual 虚函数,只用在定义中,写时不用,构造与静态不能用为虚函数。派生类和基类同同参数表的函数,不加virtual,自动成为虚函数。多态的关键是虚函数表。虚函数表会多4个字节。会有额外的开销。64位指针为8个字节。虚析构函数:定义为虚函数,析构也为虚。基类指针指向的派生类,会只删除基类析构函数。 多态的实现:动态联编,有虚函数的类,有虚函数表,4个字节,查虚函数表会浪费时间。证明虚函数表:long *p =&a
  20. 输入输出类:ios基类 iostream freopen (text.txe,w,stdout(stdin读取数据:))将标准输出重定向到test.txt文件。cerr输出错误信息。grtline读取字符。结尾会添加\0。peek(返回下一个字符)putback(将字符放回输入流)
  21. 流操纵算子:dec10 oct8 hex16 (cout<hex<n<endl)。精度分为定点(setiosflags(ios::fixed)小数点右边位数 re是取消:)和非定点(precision,setprecision(5) 连续起作用) 设置域宽一次性(输出字符数)cout<<setw(4)或者cout.width(5)包I含/0自定义流操纵算子:ostream &tab(ostream &output ){return <<\t}
  22. 文件读写:文件可以认为一个有限字符构成的顺序字符流,
  23. 类模板: typename和class可以混用,定义对象:类模板名 <真实类型参数表> 对象名(构造函数实参表)
  24. .函数模板:B提供重新性:1.继承 2.泛型程序设计 template 返回值类型 模板名 (形参表){函数体}。有模板生成函数的过程,叫做模板实例化。调用 函数名 或者<类型>(参数)函数模板和函数次序:1.先找普通函数 2.再找参数匹配模板函数 3.找实参数经过自动类型转换后能够匹配的普通函数
  25. 类模板与继承:BB
  26. string:定义:s2=abc 7=(8,x)不能用字符初始化,但可以用字符赋值。length()取长度。s1.at(i)返回引用,会做范围检查,[不会做异常检查]。比较大小:compare可以比较。sunstr求子串。swap交换字符串内容。find(“子串”,开始位置)找到返回下标。c_str()转换为char*。字符串也可以作为就输出输入。
  27. STL:C++优势之一就是便于软件的重用,在两个方面体现重用:1.面向对象的思想,继承和多态,标准类库。2.泛型程序设计的思想:模板机制,以及标准模板库STL。 容器:类模板 顺序容器:vector(动态双向数组。?不需要分配空间时。快),deque(双向队列,比vector慢,但是也是常数时间内完成,再两端增加删除快。),list(双向链表,不连续存放。增删元素在常数完成,不支持随机存取) 关联容器:set(不允许相同元素),map(有切仅有两个成员变量,不允许关键字重复),multiset排序,查找速度快。插入元素o(loh(n)) front back push_back pop-back 容器适配器:stack(栈,后进先出),queue(队列,先进先出),没有迭代器 迭代器:类似于指针,用于指向顺序容器和关联容器中的元素。定义:容器类名::iterator 变量名 ;* 迭代器元素名访问容器。++是指向下一个元素。reverse_iterator 反向迭代器,rbegin()。非常量迭代器 iterator 双向迭代器(list,set,map,只能用!=):可以。++ --以指向前后的元素。随机迭代器(vector,deque,可以用<):p+=i 将p向后移动i个元素。p+i 指向p后面的i个元素的迭代器。p[i]p后面的第i个元素。 算法:函数模板。头文件:find 左闭右开的区间 vector:在尾部头部添加,或者通过下标访问顺序是o(1),中间是o(n) list:模板链表定义迭代器的时候,要加typename 函数对象:如果一个类重载了运算符(),则该类对象为函数对象。 AA:BB
  28. C++容器:
名称特点
map提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力。注意关键字和存储对象
vector一个动态分配的数组,支持[ ]操作符和vector.at()) 高效的随机访问的容器。建议在后端插入或者删除。
list线性链表结构,多用表经常使用插入删除的地方。根据其结构可知随机检索的性能很差,需要从头开始按顺序依次查找,因此检索靠后的元素时非常耗时。即不支持[ ]操作符和.at()。
deque一种优化了的、对序列两端进行添加和删除操作、较快速地随机访问的基本序列容器。类似于vector,不同之处在于,deque提供了两级数组结构,第一级完全类似于vector,代表实际容器;另一级维护容器的首位地址。 这样,deque除了具有vector的所有功能外,还支持高效的首端插入/删除操作
// 创建vector对象
vector<int> v; // 默认初始化 空
vector<int> vec4(4, 1);//初始化4个值为1的元素
v.back(); //返回a的最后一个元素
v.front(); //返回a的第一个元素
v.pop_back(); //删除a向量的最后一个元素
v.push_back(5); //在a的最后一个向量后插入一个元素,其值为5
v.resize(10); //将a的现有元素个数调至10个,多则删,少则补,
  1. std::sort的使用方法:该函数默认是升序的,注意:左闭右开
//1 对基本类型数组从小到大排序
sort( 数组名+x1,数组名+x2)//对数组下标从x1-x2排序,不包括x2
int a[5] = {4,3,7,2,1};
sort(a,a+1);      // 4,3,7,2,1

bool cmp(int &a,int &b) {
   return a>b;
}
//2  自定义排序规则
sort(数组名+n1,数组名+n2,排序规则结构名);
排序规则结构体定义:
struct 结构名{
    bool operator()(const T &a1, const T &a2){
         return    a1<a2;// 升序   返回值为true说明a1应该排在a2前面,false则相反,
    } 
};
int b[5] = {5,4,3,2,1};
sort(b,b+4,cmp);        //5,4,3,2,1
  1. C++智能指针:分为三种
名词含义
std::auto_ptr有很多问题。 不支持复制(拷贝构造函数)和赋值(operator =),但复制或赋值的时候不会提示出错。因为不能被复制,所以不能被放入容器中。同时auto_ptr不能调用delete[],不能指向数组。在C++11中已经不建议使用
unique_ptr也不支持复制和赋值,但比auto_ptr好,直接赋值会编译出错。实在想赋值的话,需要使用:std::move。一般而言,这个智能指针实现了独占式拥有概念,意味着它可确保一个对象和其相应资源同一时间只被一个指针拥有。一旦拥有者被销毁或变成空,或开始拥有另一个对象,先前拥有的那个对象就会被销毁,其任何相应资源也会被释放。
shared_ptr基于引用计数的智能指针。可随意赋值,直到内存的引用计数为0的时候这个内存会被释放
weak_ptr弱引用。 引用计数有一个问题就是互相引用形成环,这样两个指针指向的内存都无法释放。需要手动打破循环引用或使用weak_ptr。顾名思义,weak_ptr是一个弱引用,只引用,不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。所以weak_ptr不保证它指向的内存一定是有效的,在使用之前需要检查weak_ptr是否为空指针。
shared_ptrunique_ptr的主要区别在于前者是使用引用计数的智能指针。引用计数的智能指针可以跟踪引用同一个真实指针对象的智能指针实例的数目。这意味着,可以有多个std::shared_ptr实例可以指向同一块动态分配的内存,当最后一个引用对象离开其作用域时,才会释放这块内存。shared_ptr的引用计数本身是安全且无锁的,但对象的读写则不是,因为 shared_ptr 有两个数据成员,读写操作不能原子化
//初始化
std::shared_ptr<T> p;   // 默认初始化,保存了一个空指针 T可以是任意类型
std::shared_ptr<T> p1(new T);   // 绑定到new返回的指针上
std::shared_ptr<T> p2 = std::make_shared<T>(5); 

// 创建空的shared_ptr对象
std::shared_ptr<int> p1 = std::make_shared<int>();

//分离关联
p1.reset();//不带参数
p1.reset(new int(34));  //带参数的
 

1.对于性能和内存使用有严格要求的场景,不要过于依赖智能指针。【比如嵌入式这些的,实际上C+class就够了】
2.对于类型不敏感的数据【也就是内存了】,可以考虑使用std::array或者std::vector等。因为这个时候,你实际上就是C的操作,类型对于该内存仅仅起到一个布局描述的作用,频繁的类型转换【非继承关系】、字段偏移等操作,用智能指针也没有什么好处【因为你还是会拿到裸指针去操作】
3.其他的对类型敏感,或者对作用域敏感的数据内存,可以都考虑使用智能指针。局部作用域使用uniqe_ptr , 多作用域的使用shared_ptr,缓存可能失效的情况下使用weak_ptr。
33. Boost智能指针:boost::shared_ptr是可以共享所有权的指针。如果有多个shared_ptr共同管理同一个对象时,只有这些shared_ptr全部与该对象脱离关系之后,被管理的对象才会被释放。boost::shared_ptr 也属于 boost 库,定义在 namespace boost 中,包含头文件#include<boost/smart_ptr.hpp> 便可以使用

// 初始化
boost::shared_ptr<Object> sp1(new Object());使用该方法即创建了一个管理new所申请内存shared_ptr对象
boost::shared_ptr<Object> sp1(boost::make_shared<Object>());  //make_shared支持不定参数

34.std::numeric_limits:一般来说,数值类型的极值是一个与平台相关的特性。c++标准程序库通过template numeric_limits提供这些极值,取代传统C语言所采用的预处理常数

参数含义
max返回可取的有限最大值
min返回可取的最小值(规范化)
quiet_NaN返回目标类型的安静NAN的表示
//示例
numeric_limits<int>::min();
numeric_limits<double>::max()
  1. isfinite()函数是cmath标头的库函数,用于检查给定值是否为有限值? 它接受一个值( float , double或long double ),如果该值是有限的,则返回1;否则,返回0。
  2. std::chrono 库,它是 C++11 标准时从 boost 库中引入的。 头文件是 #include
    system_clock
    这个类被称为系统内时钟,当修改系统时钟时可能会改变其单调递增的性质,静态成员函数有 now(),to_time_t(),from_time_t() 三个。
    steady_clock
    这是一个单调时钟,一旦启动之后就与系统时间没有关系了,完全根据物理是时间向前移动,成员函数只有一个 now(),通常可以用来计时,使用方法与 system_clock 相比简单许多.
    duration_cast< > 表示类型转换
// 根据时钟得到现在时间
std::chrono::system_clock::time_point today = std::chrono::system_clock::now()

// 先记录程序运行时间
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
// 做差值计算耗时
std::chrono::duration<double> duration_cost = std::chrono::duration_cast<std::chrono::duration<double> >(std::chrono::steady_clock::now() - start);
std::cout << "total cost " << duration_cost.count() << " s" << std::endl;
  1. try catch 代码块
try {
   tryCode - 尝试执行代码块 //必须。检查是否有错误的代码块。
}
catch(err) {				//err异常类名,必须(如果使用 catch)。指定局部变量应用的错误。该变量可以引用 Error 对象 (包含发生的错误信息)。如果异常通过 throw 语句创建 , 该变量引用了为在throw语句中指定的对象
   catchCode - 捕获错误的代码块 //可选。如果 try 语句发生错误执行的代码块。如果 try 语句没发生错误该代码不会执行。
}
//可选
finally {
   finallyCode - 无论 try / catch 结果如何都会执行的代码块
}
  1. getopt、getopt_long、getopt_long_only这三个函数都是为了解析命令行参数,
    #include <unistd.h>
      int getopt(int argc, char * const argv[],
                 const char *optstring);
      extern char *optarg;
      extern int optind, opterr, optopt;
      #include <getopt.h>
      int getopt_long(int argc, char * const argv[],
                 const char *optstring,
                 const struct option *longopts, int *longindex);
  1. 5555
  2. ccc
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值