C++ language Learn:
https://www.programiz.com/cpp-programming/variables-literals 
Keywords of C++ alignas(c++11)	 //声明结构体或类的对齐数
alignof(c++11)	 //查看结构体或类的对齐数
and				 //等价于 &&
and_eq			 //等价于 &&=
asm				 //汇编语句
auto			 //自动类型
bitand			 //等价于  &
bitor			 //等价于 |
bool			 //bool类型
break			 //跳出当前循环,或switch
case			 //结合switch使用
catch			 //捕获异常
char			 //1字节变量
short			 //2字节变量
signed			 //声明为有符号类型
unsigned		 //声明为无符号类型
char16_t(c++11)  //常使用于Unicode字符
char32_t(c++11)	 //常使用于Unicode字符
int				 //默认4字节
long			 //不比int类型小的类型
class			 //类,或者声明模板类型
compl			 //等价于 ~
concept(概念Ts)	 //专家级别使用
const			 //声明常变量
constexpr(c++11) //用作函数时,是在编译是进行函数调用的,类似与宏
const_cast		 //常变量强制转化为其他变量类型
continue		 //结合循环来使用	
decltype(c++11)  //与auto差不多,可以用于某个不确定多个参数类型的模板函数
default			 //结合switch来使用
delete			 //释放new出来的东西
new				 //开辟内存
do				 //配合 while构成循环
explicit		 //不能隐式构造
export			 //专家级别使用...
extern			 //改变某个变量的作用域,常用在不同文件中使用同一个变量
float			 //4字节的浮点类型
double			 //8字节的浮点类型
for				 //for循环
goto			 //跳转
if				 //判断
friend			 //给类中的一些函数使用,可以访问类中的私有成员变量
inline			 //内联声明, 编译器对该函数进行优化,类中函数和模板函数默认代这个参数
mutable			 //在lambda表达式中使用表示为传递进来的变量可以被赋值
namespace		 //声明命名空间 
noexcept(c++11)  //声明为不抛出异常,利于编译器的优化 
not				 //等价与 !
not_eq			 //等价于 !=
nullptr(c++11)	 //c++11以后声明空指针类型,主要解决模板函数中的参数问题
operator		 //操作运算重载
or				 //等价与 |
or_eq			 //等价于 |=
private			 //声明成员为私有的
public			 //声明成员为公共的
protected		 //声明成员为保护的
register		 //声明在寄存器里的变量
reinterpret_cast //常用在 一个类型的指针转化为另一个类型的指针
requires(概念TS) //一个概念,目前还没有编译器实现
return	 //函数的返回
static	 //声明变量为静态的
sizeof	 //获取某个变量的大小
static_assert(c++11) //静态断言, 常用
static_cast //静态转化
struct	 //结构体类型
switch	 //switch分支判断结构
template //声明模板
this	 //this指针, 常用在class和struct
thread_local(c++11)  //结合线程来使用
throw	 //抛出异常
true	 //bool类型的真
false	 //bool类型的假
try		 //异常尝试
typedef	 //改变变量名称
typeid	 //获取类型的id号
typename //声明模板类型
union	//联合体
using  //可以替换typedef的功能
virtual //虚函数
void   //空类型
volatile //直接声明为定死的常量
wchar_t //表示宽字符的
while   //循环
xor		//异或 ^
xor_eq  // ^=
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 #include  <iostream>  #include  <typeinfo>  #include  <cassert>  #include  <map>  using  namespace  std;struct  alignas (8 ) S {};struct  alignas (1 ) U {S s; }; struct  Foo  {int  i;float  f;char  c;struct  Empty  {};struct  alignas (64 ) Empty64 {};struct  alignas (1 ) Double { double  d; };struct  Obj  {char  a; int  b;};void  alignInfo ()  "Alignment of"  << endl"_char			 : "  << alignof (char ) << endl"_pointer          : "  << alignof (int *) << endl"_class Foo        : "  << alignof (Foo) << endl;void  showAnd ()  int  a = 3 ;int  b = 4 ;if (a == 3  && b == 4 ) {"&& a = 3, b = 4" ;if (a == 3  and  b == 4 ) {"and a = 3, b = 4" ;void  testAnd_eq ()  bool  a = false ;bool  b = true ;and_eq  a;bool  c = true ;and_eq  a;"c: "  << c << endl;void  testNot ()  bool  a = true ;	bool  b = not (a);void  testNot_eq ()  bool  a = true ;a not_eq (a)  ;void  testOr ()  int  a = 3 ;or  2 ;void  testOr_eq ()  int  a = 3 ;or_eq  4 ;void  showAsm ()  asm  ("movq $60, %rax\n\t"  "movq $2,  %rdi\n\t"  "syscall" int  get_fun (int  x)  return  x + 1 ;double  add (double  a, double  b)  return  a + b;void  showAuto ()  auto  a = 1  + 2 ;"type of a: "  << typeid (a).name () << endl;auto  b = add (1 , 1.2 );"type of b: "  << typeid (b).name () << endl;auto  c = {1 , 2 }; "type of c: "  << typeid (c).name () << endl;auto  my_lambda = [](int  x) { return  x + 3 ; };"type of my_lambda: "  << typeid (my_lambda).name () << endl;auto  my_fun = get_fun;"my_fun: "  << my_fun (3 ) << endl;"type of my_fun: "  << typeid (my_fun).name () << endl;void  showBitAndOr ()  auto  a = 3l ; auto  b = 4 ;auto  c = a bitand  b;auto  d = a bitor  b;"c: "  << c << "d: "  << d;void  testBool ()  bool  a = true ;bool  b = false ;reinterpret_cast <char  *>(&a)) = -1 ;" "  << b << endl;if (a == true ) {"i'm true" ;else  if (a == false ){"i'm false" ;else  {"What?" ;void  testBreak ()  int  a = 10 ;for (;;) {for (;;) {if (a > 1000 ) break ;if (a > 100000000 ) break ;void  testCompl ()  int  a = -3 ;int  b = compl (a); int  fact (int  n)  return  n < 1  ? 1  : (n * fact (n - 1 ));constexpr  int  factorial (int  n)  return  n < 1  ? 1  : (n * factorial (n - 1 ));template <int  N>struct  NN {void  print ()  void  testConstExpr ()  auto  a = fact (4 ); auto  b = factorial (4 ); "a: "  << a << " b: "  << b << endl;char  group[factorial (5 )];factorial (8 )> nn;print ();void  testConst_cast ()  const  int  i = 3 ;int  *p = const_cast <int *>(&i);5 ;"  "  << *p << endl;struct  A  {A (int  n) : x (n) {} double  x;};void  testDecltype ()  const  A* a = new  A (0 );auto  aa = a->x;decltype (a->x) y; decltype ((a->x)) z = y; 3 ;template <typename  T, typename  U>auto  add (T a, U b)  -> decltype (a + b)  return  a + b;struct  Base  { virtual  ~Base () {} };struct  Drive  : Base {virtual  void  name ()  void  testDynamic_cast ()  new  Base;if (Drive *d = dynamic_cast <Drive *>(b1)) {"downcast from b1 to d successful"  << std::endl;	name (); new  Drive;if (Drive *d = dynamic_cast <Drive *>(b2)) {"downcast from b2 to d successful"  << std::endl;	name (); enum  Color  { red, green, blue };void  testOldEnum ()  switch (r) {case  red:"red"  << std::endl;break ;case  green:"green"  << std::endl;break ;case  blue:"blue"  << std::endl;break ;default :"what ?"  << std::endl;enum class  NewColor  {red, green, blue = green + 12 };enum class  MyColor  : short  {black}; enum class  IsGood  {Yes, No};enum class  IsOk  {Yes, No};void  enumBoolTest (IsGood isGood, IsOk isOk)  void  testNewEnum ()  switch (r) {case  NewColor::blue: {"new blue"  << endl;						 break ;case  NewColor::red: {"new red"  << endl;						 break ;case  NewColor::green: {"new green"  << endl; break ;default :"new what?"  << endl;int  i = static_cast <int >(blue) + static_cast <int >(NewColor::blue);"blud + NewColor::blue = "  << i << endl;enumBoolTest (IsGood::Yes, IsOk::No);struct  AA  {AA (int ) {}AA (int , int ) {}operator  int ()  const  return  0 ; } struct  BB  {explicit  BB (int )  BB (int , int ) {}explicit  operator  int ()  const  return  0 ; }void  testExplicit ()  1 ; 3 , 5 }; 3 , 5 }; int  i = a1; int  na2 = static_cast <int >(a1);int  nb2 = static_cast <int >(b2); 3 ;4 ; class  MyClass  {};class  Friend  {private :int  data; friend  std::ostream &operator  << (std::ostream &out, const  Friend &o);template  <typename  T> friend  class  MyCla ;  template  <typename  T> friend  void  f (T)  public :Friend (int  x) : data (x) {}operator  int ()  const  return  this ->data; }operator  << (std::ostream &out, const  Friend &f) {return  out << f.data;class  Friend2  : public  Friend { };void  testFriend ()  44 ;void  testGoto ()  auto  i = 0 ;if (i < 5 ) {goto  NO;	inline  int  plus (int  a, int  b)  return  a + b;class  Inline  {public :void  Member ()  const  "hello\n" ; }int  vlaue ()  const  return  this ->m_value; }private :int  m_value;namespace  XGroup {class  A_  {int  value;	namespace  YGroup {class  A_  {int  value;	class  B_  {int  value;	void  testNmaespace ()  void  testNamespace2 ()  using  namespace  XGroup;using  namespace  YGroup;void  testNamespace3 ()  namespace  CGroup = XGroup;	using  YGroup::B_;namespace  {std::string astring ("long" )  ; void  testNamespace4 ()  void  noexCept ()  noexcept  "hello"  << std::endl;void  noexCept2 ()  noexcept (false )  "hello"  << std::endl;void  nullPointer (int  *a)  template <typename  T, typename  U>void  func (T t, U u)  t (u);void  testNullPointer ()  nullPointer (0 );nullPointer (NULL ); nullPointer (nullptr ); func (nullPointer, nullptr );func (nullPointer, (int *)0 );func (nullPointer, (int *)NULL );struct  Operator  {public :Operator (int  x) : data (x) { }int  operator  << (Operator const & o) const  {return  data + o.data;int  operator  & () const  { return  data; }private :int  data;void  testOperator ()  10 ;5 ;struct  AClass  {AClass () { delete  m_value;}AClass (const  AClass& rhs) : m_value (new  int (*(rhs.m_value))) {}operator  = (const  AClass& rhs) {return  *this ;private :int  *m_value;void  testReinterpret_cast ()  int  a = 1 ;auto  p = reinterpret_cast <char  *>(&a); if (p[0 ] = 1 ) {"the system is little endian\n" ;else  {"the system is big endian\n" ;struct  SizeofEmpty  {};struct  SizeofBase  { int  a;};struct  SizeofDerived  : Base{ int  b;};struct  SizeofBit  {unsigned  bit : 1 ;};void  testSizeof ()  "sizeof empty: "  << sizeof  e << endl;"sizeof derived: "  << sizeof  d << endl;"sizeof base: "  << sizeof (b) << endl;"sizeof bit: "  << sizeof (SizeofBit) << endl;static  int  globalA = 0 ;void  printInfo ()  static  int  localStatic = 0 ; "globalA: "  << globalA << " "  << "localStatic: "  << localStatic << endl;struct  Static  {static  int  s; int  Static::s = 10 ;struct  HeHe  {};struct  Static2  {static  int  a[];static  HeHe foo;static  Static2 ss;int  Static2::a[10 ];void  testStaticAssert ()  static_assert (sizeof (int ) == 4 , "only work for int of 32bit" );static_assert (sizeof (long ) == sizeof (long  long ),"only work for int of 32bit" );int  a = 5 ; int  b = 5 ;assert (a != b && "error" ); template <typename  T>void  static_assertFun ()  static_assert (alignof (T) ==4 , "only for alignof 4" );typedef  unsigned  long  ulong;class  Comp  {typedef  std::map<int , ulong> Group;void  aa ()  find (10 );using  newGroup = std::map<int , ulong>;int  main (void )  testStaticAssert ();return  0 ;
Class C++析构函数中抛出异常问题 注意: 不要在析构函数中抛出异常 
析构函数调用规则 
先调用成员析构 
再调用派生类析构 
 
问题代码 分析代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include  <iostream>  class  A  {public :A () {}A () { std::cout << "A析构了.."  << std::endl; }class  B  : public  A{public :B () {}B () { std::cout << "B析构了.. "  << std::endl; throw  std::string ("B error" ); } private :void  testClass_1 ()  new  B;delete  b;class  EvilB  : public  B {public :EvilB () noexcept (false ) { throw  std::string ("error" ); }void  testEvilB ()  try  {new  EvilB ();	delete  b;catch (std::string e) {"catch your evil: "  << e <<  std::endl;int  main (void )  testEvilB ();return  0 ;
正确做法 建议: 在类的构造函数中抛出异常 
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 #include  <iostream>  #include  <fstream>  #include  <vector>  #include  <cassert>  class  A  {public :A () {}class  B  : public  A {public :B () {}B () {  }private :class  GoodB  : public  B {public :GoodB () : m_v (new  char (10000000 )) {}GoodB (const  char * f) : m_file (f, std::ios_base::in) {if (!m_file.is_open ()) throw  std::string ("Couldn't open file..\n" );while (std::getline (m_file, line)) {push_back (line);void  doIt ( GoodB const &b)  if (b.isOpen ()) {GoodB () { assert ((!isOpen ()) && "open file: " ); }private :char  *m_v;bool  isOpen ()  const  return  !m_info.empty (); }void  test ()  int  i = 0 ;for (;;) {try  {if (i % 10000  == 0 ) std::cout << "count i: "  << i << std::endl;catch (...) {return  ;	void  test2 (char  *filename)  try  {GoodB b (filename)  ;GoodB d (filename)  ;doIt (b);catch (std::string msg) {int  main (int  argc, char ** argv)  if (argc <= 1 ) return  1 ;test2 (argv[1 ]);"exit!!!\n" ;return  0 ;
管理内存的几种方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include  <iostream>  #include  <memory>  static  void  versionOne () static  void  versionTwo () using  namespace  std;int  main (void )  versionOne ();versionTwo ();versionThree ();return  EXIT_SUCCESS;void  versionOne ()  int  *ageC = (int *) malloc (sizeof (int ));if (argC) {free (ageC);char  *c = (char *) malloc (100 );free (c);int  *age = new  int (25 );int  *height = new  int (160 );void  versionTow ()  std::shared_ptr<int > age (new  int (28 ))  ;std::shared_ptr<int > height (new  int (160 ))  ;"VersionTwo: you age is "  << *age << ", and your height is " 
逐渐退化的虚函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include  <map>  #include  <iostream>  class  Event ; class  Event  {};class  Base  {public :virtual  ~Base () {} Base (int  _id) : m_id (_id) {}virtual  void  act (Event const &)  0 ;virtual  void  print ()  const  0 ;int  id ()  const  return  m_id; } private :int  m_id;class  Drived  : public  Base { public :void  act  (Event const &) void  print ()  const Drived (int  id);Drived ();private :class  Grouped  : public  Base {public :void  act (Event const &) void  print ()  const void  addBase (Base* b) void  removeBase (int  id) Grouped (int  id);Grouped ();private :int , Base *> m_info;void  test ()  int  main (void )  test ();return  0  ;
虚函数几种实现方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include  <fstream>  #include  <iostream>  #include  <string>  #include  <vector>  struct  Base  {virtual  void  f ()  "base"  << std::endl; }virtual  void  init ()  Base () {init ();	struct  Derived  : Base { void  f ()  override  "derived overide"  << std::endl;void  init ()  override  "virtual init"  << std::endl; }struct  Derived2  : Derived {public :void  f ()  void  init ()  Base* factoryBase (int  type)   {nullptr ;if (type == 0 ) {new  Base ();	else  if (type == 1 ) {new  Derived ();	else  if (type == 2 ) {new  Derived2 ();	if (ret) ret->init ();return  ret;void  testVirtual ()  int  main (void )  testVirtual ();return  0 ;
对象内存布局 普通对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include  <iostream>  class  A  {public :A () {"A\n" ;A () {"~A\n" ;private :int  a = 1 ;int  b = 2 ;int  main ()  return  0 ;
生成可执行文件ida反编译如下:
main
1 2 3 4 5 6 7 8 9 10 int  __cdecl main (int  argc, const  char  **argv, const  char  **envp) char  v4[8 ]; unsigned  __int64 v5; 0x28 u);A ((A *)v4);A ((A *)v4);return  0 ;
A::A()
1 2 3 4 5 6 void  __fastcall A::A (A *this ) this  = 1 ;this  + 1 ) = 2 ;operator <<<std::char_traits<char >>(&std::cout, &unk_2005);
A::~A()
1 2 3 4 void  __fastcall A::~A (A *this )operator <<<std::char_traits<char >>(&std::cout, &unk_2008);
this指针即是堆栈上数据v4的地址。
在堆区上的普通对象 source
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include  <iostream>  class  A  {public :A () { std::cout << "A\n" ;}A () { std::cout << "~A\n" ;}void  test ()  "test\n" ;}private :int  a = 1 ;int  b = 2 ;int  main ()  new  A ();test ();return  0 ;
生成可执行文件ida反编译如下:
1 2 3 4 5 6 7 8 9 int  __cdecl main (int  argc, const  char  **argv, const  char  **envp) operator  new (8uLL );A (v3);test (v3);return  0 ;
A::A()
1 2 3 4 5 6 void  __fastcall A::A (A *this ) this  = 1 ;this  + 1 ) = 2 ;operator <<<std::char_traits<char >>(&std::cout, &unk_2005);
与堆栈上的差不多, 堆栈上的对象不用管内存泄漏问题,编译器调用析构函数,开辟在堆区的对象由于没有delete a,所有没有析构函数调用和内存的释放,出现内存泄漏。
拥有vital function 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include  <iostream>  class  A  {public :A () {"A\n" ;A () {"~A\n" ;virtual  void  vir_1 ()  "vir_1 A\n" ;virtual  void  vir_2 ()  0 ;private :int  a;int  b;class  B  : public  A{public :B () {std::cout << "B\n" ;}	B () {std::cout << "~B\n" ;}	virtual  void  vir_2 ()  private :int  a = 4 ;int  main ()  return  0 ;
 生成可执行文件ida反编译如下:
main
1 2 3 4 5 6 7 8 9 10 int  __cdecl main (int  argc, const  char  **argv, const  char  **envp) char  v4[24 ]; unsigned  __int64 v5; 0x28 u);B ((B *)v4);B ((B *)v4);return  0 ;
B::B()
1 2 3 4 5 6 7 8 9 10 11 12 13 void  __fastcall B::B (B *this ) A (this ); this  = off_3D68; this  + 4 ) = 4 ;operator <<<std::char_traits<char >>(&std::cout, "B\n" );
A::A()
1 2 3 4 5 6 7 8 9 10 void  __fastcall A::A (A *this ) this  = &off_3D88; operator <<<std::char_traits<char >>(&std::cout, &unk_2005);
B::~B() 
1 2 3 4 5 6 void  __fastcall B::~B (B *this )this  = off_3D68; operator <<<std::char_traits<char >>(&std::cout, "~B\n" );A (this );
A::~A()
1 2 3 4 5 void  __fastcall A::~A (A *this )this  = &off_3D88; operator <<<std::char_traits<char >>(&std::cout, &unk_2008);
由以上看类中的内容是储存在ptr + 1之后的,第一个用于储存虚函数表的地址。
ref: https://www.cnblogs.com/qg-whz/p/4909359.html 
基本原则 C++98 类的基本三大原则 
类的构造 
类的析构 
类的复制 
 
若c++98中,不想复制的话,把构造函数设为私有变量, 并不实现构造函数
C++11 类的基本五大原则 前面三点基于c++98,增加了两个原则
5 可以对拷贝构造函数和operator=进行右值引用进行重载 
 
也就是采用左值或者右值进行构造,编译器会对不同的构造函数进行构造.
代码例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 #include  <iostream>  #include  <string>  #include  <vector>  #include  <cstring>  #include  <cassert>  class  RuleOfFive ;  class  Parent ;class  Child  {public :explicit  Child (Parent *p)  : m_parent(p) {private :class  Parent  {public :bool  addChild (Child* child)  emplace_back (child); }private :class  RuleOfThree  {public :RuleOfThree (const  char * arg) : cstring (new  char [std::strlen (arg) + 1 ]){ strcpy (cstring, arg); RuleOfThree () {delete [] cstring;	RuleOfThree (const  RuleOfThree& other)  = delete ;operator  = (const  RuleOfThree& other) {char  *tmp_cstring = new  char [std::strlen (other.cstring) + 1 ];	strcpy (tmp_cstring, other.cstring);delete [] cstring;private :char * cstring;class  RuleOfFive  {public :RuleOfFive (RuleOfFive&& rhs) {"右值构造.."  << std::endl;nullptr ;RuleOfFive () : m_value (new  int (10 ) ) {}RuleOfFive (const  RuleOfFive &rhs) : m_value (new  int (* (rhs.m_value))) {"左值或者右值构造.."  << std::endl;operator  = (const  RuleOfFive &rhs) {delete  m_value; return  *this ;operator =(RuleOfFive&& rhs) {nullptr ;return  *this ;void  print ()  const  assert (m_value && "class print: " ); "value: "  << *m_value << std::endl;RuleOfFive () { delete  m_value; }private :int  *m_value;void  leftOrRight ()  int  a = 0 ;int  b;int  c = 2  + 3 ;int  d = a + c;auto  address = &a;int & e = a; int && e3 = 3 ; void  leftAndRight ()  int > a; for (int  i = 0 ; i < 10 ; ++i) a.push_back (i);auto  b = a; auto  &c = b; auto  d = std::move (b);RuleOfFive g (f)  ; RuleOfFive h  (std::move(f))  ; int  main (void )  leftAndRight ();return  0 ;
STL STL 是一个框架, 将数据结构和算法进一步的抽象, 包含了容器, 迭代器, 算法
迭代器: 容器之间统一的一个查询元素接口,可以用来遍历容器的元素
算法:  查找, 排序, 修改…
类别 1 序列式容器 array / vector / deque/list / forward_list		 一般实现方式: 数组 ,指针 链表
新型: regex (正则表达式), 增强了 rand算法, thread(线程), async, furture, time
容器内元素的条件 
必须可以复制(copy) 或则搬移(move) (隐含的条件是在拷贝和搬移的过程中应该没有副作用)  
c++ 的基本类型满足以上要求: bool char int int* char*, reference 
元素必须可以被赋值操作,来作为复制或者搬移, (因为容器和算法对复写有要求) 
元素可以被销毁 
 
针对于不同的容器还有特殊的要求
对于序列式容器, 元素必须有默认的构造函数 
对于某些操作,元素需要定义 == 
对于关联式容器, 排序默认准则的是 <  
无顺序容器,必须要提供一个hash函数 
 
stl容器里面存的是元素的值而不是引用,到底我们的容器里面应该存的东西是什么呢?
STL对于错误怎么处理
实例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 #include  <iostream>  #include  <chrono>  #include  <algorithm>  #include  <list>  #include  <map>  #include  <random>  #include  <set>  #include  <string>  #include  <unordered_map>  #include  <unordered_set>  #include  <vector>  #include  <deque>  template <typename  T>void  containerAllInterface (T &a, T &b)  T d (a)  ; T f (std::move(a))  ; auto  iterB = b.begin ();auto  iterE = b.end ();typename  T::iterator iterF = b.begin ();T g (b.begin(), b.end())  ; T g2 (iterB, iterE)  ; size (); empty ();  max_size ();if (b == c) {} if (b != d) {} if (b < e) {}  move (b);swap (g); swap (e, g); cbegin (); auto  ea = e.cbegin ();auto  eea = e.cbegin ();cend ();clear (); void  test_container ()  int > a;int > b;int >>(a, b);int > e;int > f;int >>(e, f);int > g;int > h;int >>(g, h);int  main (int , char **)  return  0 ;
vector vector 是c++98中引入的动态数组(dynamic array)
1 2 3 4 namespace  std {template <typename  T, typename  Allocator = allocator<T>> class  vector;
特点
随机访问元素, 末端添加删除元素效率最高, 前端和中间删除和添加元素效率最低,存在当前容器大小和容量的关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 #include  <vector>  #include  <iostream>  #include  <cstring>  static  void  vectorPart ()  using  Group = std::vector<float >;Group c (a)  ; Group d (10 )  ; Group e (10 , 1.0f )  ; Group f (e.begin(), e.end())  ; Group g ({1.0f , 2.0f , 3.0f })  ; 1.1f , 2.1f , 3.1f };1.2f , 2.2f , 3.2f , 4.2f }; empty ();size (); max_size (); capacity (); reserve (100 ); shrink_to_fit (); assign (3 , 1.0f ); assign (g.begin (), g.end ());assign ({1.0f , 2.0f , 3.0f });swap (a);swap (a, b); 0 ];at (0 ); if (b.empty ()) {front (); back ();front ();back ();begin ();end ();cbegin ();cend ();rbegin ();rend ();crbegin ();crend ();pop_back (); erase (b.begin ()); erase (b.begin (), b.end ()); push_back (10.0f ); pop_back (); auto  iter = b.insert (b.end (), 100.0f ); insert (b.end (), 10 , -10.0f ); insert (b.end (), h.begin (), h.end ()); emplace (b.end (), 10.0f ); emplace_back (10.0f ); resize (10 ); resize (100 , 1.0f ); clear (); shrink_to_fit (); std::vector<char > carr (100 , 0 )  ;strcpy (&carr[0 ], "hello World\n" ); printf ("%s" , carr.data ());printf ("%s" , carr.begin ());int  main (int , char **)  return  0 ;
deque deque是c++98中引入的动态数组(dynamic array)
1 2 3 4 namespace  std {template <typename  T, typename  Allocator = allocator<T>>class  deque;
特点
随机访问元素, 末端和头部添加删除元素效率高,中间删除和添加元素效率低,而vector仅仅操作尾部效率高,元素的访问和迭代比vector要慢,迭代器不能是普通的指针。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 #include  <deque>  #include  <vector>  using  Group = std::deque<float >;static  void  dequePart ()  Group c (a)  ;Group d (10 )  ;Group e (10 , 1.0f )  ;Group f (e.begin(), e.end())  ;Group g ({1.0f , 2.0f , 3.0f })  ;1.0f , 2.0f , 3.0f };1.0f , 2.0f , 3.0f };if (!a.empty ()) a.pop_back ();empty ();size ();max_size ();shrink_to_fit (); swap (a); swap (a, b);0 ];at (0 );front ();back ();begin ();end ();cbegin ();cend ();rbegin ();rend ();crbegin ();crend ();pop_back ();push_back (1.0f );push_front (1.2f ); emplace_front (1.0f );auto  iter = b.insert (b.end (), 100.0f ); insert (b.end (), 10 , -10.0f );insert (b.end (), h.begin (), h.end ());emplace (b.end (), 10.0f );emplace_back (10.0f );resize (10 );resize (100 , 10.0f );clear ();shrink_to_fit (); int  main (void )  return  0 ;
list list 是c++98中引入的双向串列(double linked list)
1 2 3 4 namespace std {
特点
 不支持随机访问元素,访问头部和尾部元素快
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 #include  <list>  #include  <cassert>  #include  <iostream>  static  void  listPart ()  using  Group = std::list<float >;Group c (a)  ;Group d (10 )  ;Group e (10 , 1.0f )  ;Group f (e.begin(), e.end())  ;Group g ({1.0f , 2.0f , 3.0f })  ;1.0f , 2.0f , 3.0f };1.0f , 2.0f , 3.0f };empty ();size ();max_size ();assign (3 , 1.0f );assign (g.begin (), g.end ());assign ({1.0f , 2.0f , 3.0f });swap (a);swap (a, b);front ();back ();begin ();end ();cbegin ();cend ();rbegin ();rend ();crbegin ();crend ();resize (10 );auto  iterBegin = a.begin ();assert (a.size () >= 10 );advance (iterBegin, 0 ); for (; iterBegin != a.end (); ++iterBegin) std::cout << *iterBegin << " " ;pop_back (); if (!a.empty ()) a.pop_back ();erase (b.begin ());erase (b.begin (), b.end ());push_back (10.0f );pop_back ();push_front (1.2f );emplace_front (1.3f );auto  iter = b.insert (b.end (), 100.0f );insert (b.end (), 10 , -10.0f );resize (5 );resize (10 , 1.2f );remove (1.0f ); remove_if ([](auto  v) { return  v > 100.0f ; }); reverse (); sort (); merge (g); unique (); splice (c.begin (), b); int  main (void )  listPart ();return  0 ;
forward_list //forward_list 是c++11中引入的单项串列(singal linked list)
1 2 3 4 namespace  std {template  <typename  T, typename  Allocator = allocator<T>>class  forward_list;
特点
不支持随机元素访问, 访问头部元素速度快,”forward_list” 和自己手写的c-style signal linked list相比没有任何时间和空间上的额外开销, 任何性质如果和这个目标抵触,我们就放弃该特征.任何位置插入和删除元素都很快, 常亮时间完成。插入和删除不会造成迭代器失效,对于异常支持好, 出现异常对于forward_lit而言, 要么不成功, 要么没什么影响。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 #include  <forward_list>  #include  <iostream>  static  void  forwardListPart ()  using  Group = std::forward_list<float >;Group c (a)  ;Group d (10 )  ;Group e (10 , 1.0f )  ;Group f (e.begin(), e.end())  ;Group g ({1.0f , 2.0f , 3.0f })  ;1.0f , 2.0f , 3.0f };1.0f , 2.0f , 3.0f };empty ();max_size ();assign (3 , 1.0f );assign (g.begin (), g.end ());assign ({1.0f , 2.0f , 3.0f });swap (a);swap (a, b);front ();begin ();end ();cbegin ();cend ();before_begin (); cbefore_begin ();  auto  iterBegin = a.begin ();empty ();erase_after (b.begin ()); erase_after (b.before_begin ()); erase_after (b.begin (), b.end ()); push_front (1.2f );emplace_front (1.3f );auto  iter = b.insert_after (b.before_begin (), 100.0f );insert_after (b.before_begin (), 10 , -10.0f );insert_after (b.before_begin (), h.begin (), h.end ());resize (10 );resize (100 , 1.0f );remove (1.0f );remove_if ([](auto  v) { return  v > 100.0f ; });sort (); sort ();merge (g); unique (); splice_after (c.before_begin (), b);int  main (void )  int > forlist = {1 , 2 , 3 , 4 , 5 , 6 };auto  fiter = forlist.before_begin ();for (int  i = 0 ; i < 2 ; ++i, ++fiter);insert_after (fiter, 10 );for (fiter = forlist.begin (); fiter != forlist.end (); ++fiter) std::cout << *fiter << " "  ;return  0 ;
array array 实际上是对c/c++语言中的原生数组进行了封装
1 2 3 4 namespace  std {template <typename  T, size_t  N>class  array ;
特点
 内存分配在栈(stack), 绝不会重写分配.随机访问元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include  <iostream>  #include  <array>  #include  <cstring>  template <typename  C>void  checkSize (C &c)  if (c.size () > 3 ) {3 ] = 10 ; at (3 ) = 10 ;void  arrayPart ()  int , 100> a; int , 100> b = {}; int , 5> obj = {1 , 2 , 3 , 4 , 5 };int , 5> obj2 = {1 }; empty (); size ();max_size ();auto  aa = a;swap (a); 1 ]; at (1 ); front (); back ();  checkSize (a);begin (); end ();cbegin (); cend ();rbegin (); rend ();crbegin (); crend ();char , 100> carr;strcpy (&carr[0 ], "hello world\n" );printf ("%s" , &carr[0 ]); printf ("%s" , carr.data ());printf ("%s" , carr.begin ());auto  info = std::get <1 >(carr); printf ("%c\n" , info); fill (0 ); int  main (void )  arrayPart ();return  0 ;
C++中的补码公式与位域 补码公式 -x = x+1 = ~(x-1)x) = x+1
x+y = x - y-1 = (x|y) + (x&y)y) - (x&y)x|y) - ~x
x==y :  (x-y|y-x)y) & ((x^y) | (y-x))x&y) | ((x|y) & (x-y))   //unsignedx|y) & ((x^y) | ~(y-x))   //unsigned
实例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include  <iostream>  using  namespace  std;void  operator_1 (void ) void  operator_2 (void ) void  operator_3 (void ) int  main (void )  operator_1 ();operator_2 ();operator_3 ();return  0 ;void  operator_1 (void )  int  x = 1 ;"-x = "  << -x << "   ~x+1 = "  << ~x + 1  << endl;"~x = "  << ~x << "   -x-1 = "  << -x - 1  << endl;"-(~x) = " << -(~x) << "   x+1 = "  << x + 1  << endl;"-(~x) = " << -(~x) << "   x-1 = "  << -x -1  << endl;void  operator_2 (void )  int  x = 3 , y = 5 ;"x: "  << x << "y: "  << y << endl;"x+y="  << x+y << "   x- ~y-1= "  << x - ~y - 1 "  (x|y)+(x&y) = "  << (x|y) + (x&y) << endl;"x-y="  << x-y << "   x+ ~y+1= "  << x + ~y + 1 "  (x|~y) - (~x&y) = "  << (x|~y) - (~x|y) << endl;"x^y="  << (x^y) << " (x|y) - (x&y)"  << (x|y) - (x&y) << endl;"x|y="  << (x|y) << " (x& ~y) + y = "  << (x& ~y) + y << endl;"x&y="  << (x&y) << " (~x|y) - ~x = "  << (~x|y) - ~x << endl;void  operator_3 (void )  int  x = -3 , y = -5 ;unsigned  int  x_t  = -1 , y_t  = -5 ;"x: "  << x << "y: "  << y << endl;"x==y ="  << (x==y) << "  ~(x-y|y-x) ="  << ~(x-y|y-x) << endl;"x!=y ="  << (x!=y) << "  x-y|y-x ="  << (x-y|y-x) << endl;"x<y ="  << (x<y) << "  (x-y) ^ ((x^y) & ((x-y)^x))="  << ((x-y) ^ ((x^y) & ((x-y)^x))) << endl;"x<=y ="  << (x<=y) << "  (x|~y) & ((x^y) |~ (y-x))="  << ((x|~y) & ((x^y) |~ (y-x))) << endl;"unsigned: x<y ="  << (x_t <y_t )"  (~x&y) | ((~x|y) & (x-y))"  << ((~x_t &y_t ) | ((~x_t |y_t ) & (x_t -y_t ))) << endl;"unsigned: x<=y ="  << (x_t <=y_t )" (~x|y) & ((x^y) | ~(y-x) ="  << ((~x_t |y_t ) & ((x_t ^y_t ) |~ (y_t -x_t ))) << endl;
位域 在结构内声明位域的形式如下:
1 2 3 4 struct
下面是有关位域中变量元素的描述:
元素 
描述 
 
 
type 
只能为 int(整型),unsigned int(无符号整型),signed int(有符号整型) 三种类型,决定了如何解释位域的值。 
 
member_name 
位域的名称。 
 
width 
位域中位的数量。宽度必须小于或等于指定类型的位宽度。 
 
实例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include  <stdio.h>  typedef  struct  bs  {int  a:2 ;int  b:1 ;int  c:12 ;unsigned  d:4 struct  bit_2  {unsigned  a:2 ;unsigned  :2 ;  unsigned  :0 ;  unsigned  b:4 ;unsigned  c:4 ;int  main (void )  printf ("sizeof(%d) \n" ,sizeof (struct  bs));4 ;1 ;34235 ;printf ("a: %d   b: %d  c: %d\n" , bit.a, bit.b, bit.c);return  0 ;
lambda 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 #include  <functional>  #include  <iostream>  void  printInfo (int  a, int  b, int  c)  " a "  << a << " b "  << b << " c "  << c << std::endl;struct  Print  {void  operator ()  (int  a, int  b, int  c)  const  " a "  << a << " b "  << b << " c "  << c << std::endl;template <typename  T1, typename  T2, typename  T3>void  templatePrint (T1 a, T2 b, T3 c)  " a "  << a << " b "  << b << " c "  << c << std::endl;struct  TemplatePrint  {template <typename  T1, typename  T2, typename  T3>		void  operator ()  (T1 a, T2 b, T3 c)  const   {" a "  << a << " b "  << b << " c "  << c << std::endl;inline  void  print (int  a, int  b, int  c)  " a "  << a << " b "  << b << " c "  << c << std::endl;template <typename  Fun>void  printUseFun (Fun fun, int  a, int  b, int  c)  fun (a, b, c);void  test_1 ()  printInfo (1 , 2 , 3 );printUseClass (1 , 2 , 3 ); templatePrint (1 , 2 , 3 ); printUseTempClass (1 , 2 , 3 );print (1 , 2 , 3 );"lamda: "  << std::endl;auto  local = [](int  a, int  b, int  c) {" a "  << a << " b "  << b << " c "  << c << std::endl;printUseFun (local, 1 , 2 , 3 );printUseFun ([](int  a, int  b, int  c) {"lamda2:"  << std::endl;	" a = "  << a << " b = "  << b << " c = "  << c << std::endl;2 , 3 , 5 );int  a = 6 , b = 7 , c = 8 ;auto  local2  = [a, b, c]() {" a = "  << a << " b = "  << b << " c = "  << c << std::endl;local2 ();auto  local3 = [=]() {"===="  << std::endl;" a = "  << a << " b = "  << b << " c = "  << c << std::endl;local3 ();auto  local4 = [=]() mutable  {"===="  << std::endl;4 , b = 4  , c = 4 ;" a = "  << a << " b = "  << b << " c = "  << c << std::endl;local4 ();int  main (void )  test_1 ();return  0 ;
C++11新型for循环,auto, 类成员的初始化及左右值引用 C++11中新型for循环,auto, 类成员的初始化及左右值引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 #include  <typeinfo>  #include  <iostream>  #include  <string>  #include  <vector>  #include  <iterator>  static  void  autoValue () static  void  autoPointer () static  void  newVersionFor () static  void  newVersionConstruct () static  void  defaultInitValue () static  void  leftRefAndRightRef () class  MyVector  {public :using  GroupType = std::vector<int >;public :void  push_back (int  x)  push_back (x);GroupType::iterator begin (MyVector &v)   {return  v.m_group.begin ();GroupType::iterator end (MyVector &v)   {return  v.m_group.end ();void  testMyClass ()  push_back (1 );push_back (2 );push_back (3 );for (auto  i : mv) {" " ;	int  main (int  , char ** )  testMyClass ();leftRefAndRightRef ();return  0 ;static  void  autoValue ()  auto  age = 10 ;auto  name = std::string ("Yt" );auto  height = 160.0f ;auto  wight = 72.0 ;"age is type "  << typeid (age).name () << std::endl;"name is type "  << typeid (name).name () << std::endl;"height is type "  << typeid (height).name () << std::endl;"weight is type "  << typeid (wight).name () << std::endl;static  void  autoPointer ()  auto  age = new  int (10 );auto  name = "Yt" ;auto  height = new  float (160.0f );auto  wight = new  double (72.0 );"age is type "  << typeid (age).name () << std::endl;"name is type "  << typeid (name).name () << std::endl;"height is type "  << typeid (height).name () << std::endl;"weight is type "  << typeid (wight).name () << std::endl;static  void  newVersionFor ()  int  ids[] = {1 , 2 , 3 , 4 , 5 };"new version" ;for (auto  v : ids) {" " ;	"old version" ;for (int  i = 0 ; i < sizeof (ids) / sizeof (ids[0 ]); ++i) {" " ;	int > group;for (int  i = 0 ; i < 4 ; ++i) group.push_back (i);for (std::vector<int >::size_type i = 0 , size = group.size (); i < size; ++i) {"iterator: "  << std::endl;for (std::vector<int >::const_iterator iter = group.begin (); iter != group.end (); ++iter) {" " ;	"vector old version:"  << std::endl;for (auto  v : group) {" " ;"vector new version:"  << std::endl;for (auto  &v : group) {1 ;for (const  auto  &v : group) {" " ;class  A  {public :explicit  A (int  value)  : m_value(value) {private :int  m_value;static  void  newVersionConstruct ()  A a (10 )  ;3 };int  avector[] = {1 , 2 , 3 };int > bv;for (auto  v : avector) bv.push_back (v);int > cv = {1 , 2 , 3 };int > v {1 , 2 , 3 };A c (true )  ;A d (false )  ;A e (1.0 )  ;class  B  {public :B () : m_age (18 ), m_height (170 ), m_weight (75 ) {}explicit  B (int  age)  : m_age(age), m_height(170 ), m_weight(75 ) {B (int  age, int  height) : m_age (age), m_height (height) {}int  age ()  const  return  m_age; }int  height ()  const  return  m_height; }int  weight ()  const  return  m_weight; }private :int  m_age;int  m_height;int  m_weight;class  NewB  {public :NewB () {}explicit  NewB (int  age)  : m_age {NewB (int  age, int  height) : m_age{age}, m_height {height} {}int  age ()  const  return  m_age; }int  height ()  const  return  m_height; }int  weight ()  const  return  m_weight; }void  p ()  const  " "  << m_fightValue;}private :int  m_age = 18 ; int  m_height = 170 ;int  m_weight = 75 ;int  m_value{}; double  m_fightValue{}; static  void  defaultInitValue ()  B a (10 , 20 )  ;NewB b (10 , 20 )  ;"Old a age is"  << a.age () << "height "  << a.height ()" wight "  << a.weight () << std::endl;"New b age is"  << b.age () << "height "  << b.height ()" wight "  << b.weight () << std::endl;p ();static  void  leftRefAndRightRef ()  int  a = 10 ;int  &refA = a;const  int  &constRefA = a;" a"  << a << " ref of a "  << refA << " const ref a " const  int  &constRefB = 10 ; "different version const ref "  << constRefB << std::endl;int  &&rrB = 20 ;const  int  &&crrB = 20 ;30 ; " right ref of b "  << rrB << " const right ref b " int  b = 20 ;int  &&newRRB = std::move (b); const  int  &&cNewRRB = std::move (b);" b "  << b << " right ref of be "  << newRRB << "const right ref b " "address "  << &b << " ref "  << &newRRB << " c ref "  << &cNewRRB << std::endl;
C++11智能指针 目前c++ 的4种指针
auto_ptr  c++98 智能指针,使用了
shared_ptr //共享指针
unique_ptr //只能由一个使用者使用
weaked_ptr //与share_ptr搭配使用
 
shared_patr 实例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 #include  <iostream>  #include  <memory>  static  void  interfaceOfSharedPtr () int  main (void )  interfaceOfSharedPtr ();return  0 ;class  Object  {public :Object (int  id) : m_id (id) { std::cout << "init obj "  << m_id << std::endl; };Object () { std::cout << "bye bye "  << m_id << std::endl; }int  id ()  const  return  m_id; }private :int  m_id = 0 ;using  ObjectPtr = std::shared_ptr<Object>;void  print (ObjectPtr obj)  "count "  << obj.use_count () << " id "  << obj->id () << std::endl;void  printRef (const  ObjectPtr &obj)  "ref count "  << obj.use_count () << "id "  << obj->id () << std::endl;static  void  interfaceOfSharedPtr ()  "ref count is "  << null.use_count () << std::endl;ObjectPtr obj  (new  Object(1 ))  ;	"ref count is "  << obj.use_count () << std::endl;ObjectPtr obj2 (obj)  ;"ref count is "  << obj2.use_count () << std::endl;"ref count is "  << obj.use_count () << std::endl;reset (); "ref count is "  << obj.use_count () << std::endl;swap (obj4); "obj4 ref count is "  << obj4.use_count () << std::endl;swap (obj3, obj4); "obj4 ref count is "  << obj4.use_count () << std::endl;auto  p = obj.get ();if (p) {"id is"  << p->id () << std::endl;	if (obj) { "p id is "  << obj->id () << std::endl; "ref id is "  << (*obj).id () << std::endl; nullptr ;"only one hold ptr "  << obj.unique () << std::endl; "judge differnt: "  << std::endl;"use_count: "  << obj.use_count () << std::endl;printRef (obj);print (obj);"use_count: "  << obj.use_count () << std::endl;void  deleterOfObject (Object *obj)  if (obj)"delete obj "  << obj->id ()  << std::endl;delete  obj;void  useDeleter ()  ObjectPtr obj (new  Object(2 ), deleterOfObject)  ;
weak_ptr c++智能指针-shared_ptr的尴尬-诞生weak_ptr
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 #include  <iostream>  #include  <memory>  #include  <cassert>  class  Parent ; using  ParentPtr = std::shared_ptr<Parent>;typedef  std::weak_ptr<Parent> WeakParentPtr;class  Child  {public :Child () { std::cout << "Child!!"  << std::endl; }Child ();typedef  std::shared_ptr<Child> ChildPtr;typedef  std::weak_ptr<Child> WeakChildPtr;class  Parent  {public :Parent () { std::cout << "Parent!!"  << std::endl; }void  print ()  const  "use_count: "  << this ->son.use_count () << std::endl;}Parent ();class  Object  {public :Object (int  id) : m_id (id) { std::cout << "init obj "  << m_id << std::endl; };Object () { std::cout << "bye bye "  << m_id << std::endl; }int  id ()  const  return  m_id; }private :int  m_id = 0 ;using  ObjectPtr = std::shared_ptr<Object>;Child () { std::cout << "bye child!"  << std::endl; }Parent () { std::cout << "bye parent!"  << std::endl; }void  testParentAndChild ()  ParentPtr p (new  Parent())  ;ChildPtr c (new  Child())  ;print ();void  sharedPtrWithWeakPtr ()  ObjectPtr obj (new  Object(1 ))  ;typedef  std::weak_ptr<Object> WeakObjectPtr;WeakObjectPtr weakObj (obj)  ;WeakObjectPtr weakObj2 (obj)  ;"obj use count is "  << obj.use_count () << std::endl;auto  p = weakObj.lock (); "expired: "  << weakObj.expired () << std::endl; if (p) {unique () << std::endl; else  {reset (); "endl;" ;auto  p2 = weakObj.lock (); reset (new  Object (2 )); auto  p = weakObj.lock ();if (p) {assert (false );else  {"changed!"  << std::endl;"expired: "  << weakObj.expired () << std::endl; int  main (void )  testParentAndChild ();return  0 ;
shared_ptr储存this指针多次析构问题 enable_shared_from_this解决方案 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 #include  <iostream>  #include  <memory>  #include  <cassert>  class  Parent ;typedef  std::shared_ptr<Parent> ParentPtr;typedef  std::weak_ptr<Parent> WeakParentPtr;class  Child  : public  std::enable_shared_from_this<Child> {public :Child ();Child ();void  checkRelation () typedef  std::shared_ptr<Child> ChildPtr;typedef  std::weak_ptr<Child> WeakChildPtr;class  Parent  : public  std::enable_shared_from_this<Parent> {public :Parent ();Parent ();void  checkRelation () void  handleChildAndParentRef (const  Parent &p, const  Child &c)  if (c.father.lock ().get () == &p && p.son.lock ().get () == &c) {"right relation"  << std::endl;	else  {"oop!!!!!!"  << std::endl;void  handleChildAndParent (const  ParentPtr &p, const  ChildPtr &c)  assert (c);assert (p);if (c->father.lock () == p && p->son.lock () == c) {"right relation"  << std::endl;	else  {"oop!!!!!!"  << std::endl;Child () { std::cout << "hello child"  << std::endl; }Child () { std::cout << "bye child"  << std::endl; }Parent () { std::cout << "hello parent"  << std::endl; }Parent () { std::cout << "bye parent"  << std::endl; }void  Parent::checkRelation ()  auto  ps = son.lock ();if (ps) {handleChildAndParent (shared_from_this (), ps);	"after call checkRelation"  << std::endl;void  Child::checkRelation ()  void  testParentAndChild ()  ParentPtr p (new  Parent())  ;ChildPtr c (new  Child())  ;checkRelation ();static  void  interfaceOfSharedPtr () static  void  sharedPtrWithWeakPtr () static  void  uniquePtr () int  main (void )  testParentAndChild ();	return  0  ;
unique_ptr 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 #include  <iostream>  #include  <memory>  #include  <cassert>  class  Object ;typedef  std::unique_ptr<Object> UniqueObjectPtr;using  ObjectPtr = std::shared_ptr<Object>;void  print (const  UniqueObjectPtr& obj)  class  Object  {public :Object (int  x) : m_id (x) { std::cout << "Hello Obj"  << std::endl; };Object () { std::cout << "Bye Obj"  << std::endl; };int  id ()  return  m_id; }private :	int  m_id = 0 ;void  transfer (UniqueObjectPtr obj)  id () << std::endl;void  uniquePtr ()  new  Object (1 ) };auto  p = obj.get (); if (p) {if (obj) {id () << " "  << obj->id () << " "  << (*obj).id () << " "  << std::endl;print (obj);release (); "release: unique_ptr"  << std::endl;delete  p; reset (new  Object (2 )); transfer (std::move (obj)); assert (obj == nullptr );reset (new  Object (3 ));ObjectPtr sharedObj (std::move(obj))  ;assert (obj == nullptr );int  main (void )  uniquePtr ();return  0 ;
智能指针总结 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include  <iostream>  #include  <memory>  #include  <cassert>  void  sharedPtrNotice () class  Parent ;typedef  std::shared_ptr<Parent> ParentPtr;typedef  std::weak_ptr<Parent> WeakParentPtr;class  Child  : public  std::enable_shared_from_this<Child> {public :	Child ();Child ();class  Object  {public : Object (int  x) : m_value (x) { }private :int  m_value = 0 ;using  ObjectPtr = std::shared_ptr<Object>;void  sharedPtrNotice ()  make_shared <Object>(3 ); Object obj6 (4 )  ; std::unique_ptr<Object> puObj (new  Object(1 ))  ; make_shared <Object>(3 ); int  main (void )  return  0 ;