0%

C++基础

[toc]

C++ 基础

类型

类型长度与操作系统位数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

using namespace std;

int main()
{
cout<<"sizeof(char): "<<sizeof(char)<<endl;
cout<<"sizeof(unsigned char): "<<sizeof(unsigned char)<<endl;
cout<<"sizeof(short): "<<sizeof(short)<<endl;
cout<<"sizeof(int): "<<sizeof(int)<<endl;
cout<<"sizeof(unsigned int): "<<sizeof(unsigned int)<<endl;
cout<<"sizeof(double): "<<sizeof(double)<<endl;
cout<<"sizeof(long): "<<sizeof(long)<<endl;
cout<<"sizeof(long long): "<<sizeof(long long)<<endl;

return 0;
}

使用gcc编译32位/64位程序

1
2
g++ -m64 hello.cpp -o hello-64
g++ -m32 hello.cpp -o hello-32

在编译32位程序时,可能提示如下错误

1
/usr/include/c++/9/iostream:38:10: fatal error: bits/c++config.h: 没有那个文件或目录

ubuntu系统可以执行如下命令解决

1
sudo apt-get install gcc-multilib g++-multilib

32位和63位程序类型长度

从程序执行结果可以看出,32位程序和64位程序仅long类型长度不同,其他类型的长度是一致。

C++11 新特性

右值引用

C++98中就存在引用语法,而C++11标准中新增了右值引用的语法特性,因此为了区分两者,将C++11标准出现之前的引用称为左值引用。

智能指针

C++的指针包括原始指针(raw pointer)和智能指针(smart pointer)两种,智能指针是原始指针的封装,会自动释放内存,正确使用可以解决内存泄漏的问题。

std::unique_ptr

独占指针,在任何给定的时刻,只能有一个指针管理内存,当指针超出作用域时,内存会自动释放;该类型指针不可以拷贝,只允许移动 ,通过std::move转移内存所有权。

创建方式:

  • 通过已有的原始指针创建;
  • 通过new创建;
  • 通过std::make_unique方式创建(C++14新特性,推荐使用);

示例

puppy.h

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
#include <iostream>

#ifndef _PUPPY_H
#define _PUPPY_H

class Puppy {
public:
Puppy(std::string name) : name_(name)
{
std::cout << "Puppy constructor." << std::endl;
}

Puppy() = default;

~Puppy()
{
std::cout << "Puppy desconstructor." << std::endl;
}

void ShowPuppyInfo(void)
{
std::cout << "Puppy name: " << name_ << std::endl;
}

std::string GetName(void)
{
return name_;
}

void SetPuppyName(const std::string &name)
{
name_ = name;
}
private:
std::string name_{"example"};
};

#endif /* _PUPPY_H */

main.cpp

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
#include <iostream>
#include <memory>
#include "puppy.h"

int main(int argc, char *argv[])
{
{
Puppy husky("HaShiQi");
husky.ShowPuppyInfo();
}

Puppy *poodle = new Puppy("TaiDi");
poodle->ShowPuppyInfo();
delete poodle;

// std::unique_ptr<Puppy> shibalnu{new Puppy("ChaiQuan")}; // not good
std::unique_ptr<Puppy> shibalnu = std::make_unique<Puppy>("ChaiQuan"); // good
std::cout << "Puppy unique pointer address: " << shibalnu.get() <<std::endl; // print memory address
shibalnu->ShowPuppyInfo();

std::unique_ptr<Puppy> corgi = std::move(shibalnu);
std::cout << "Puppy unique pointer address: " << shibalnu.get() <<std::endl; // print memory address
std::cout << "Puppy unique pointer address: " << corgi.get() <<std::endl; // print memory address
corgi->SetPuppyName("KeJi");
corgi->ShowPuppyInfo();
// shibalnu->ShowPuppyInfo(); // segment fault

return 0;
}

代码执行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
Puppy constructor.
Puppy name: HaShiQi
Puppy desconstructor.
Puppy constructor.
Puppy name: TaiDi
Puppy desconstructor.
Puppy constructor.
Puppy unique pointer address: 0x56103912dec0
Puppy name: ChaiQuan
Puppy unique pointer address: 0
Puppy unique pointer address: 0x56103912dec0
Puppy name: KeJi
Puppy desconstructor

std::shared_ptr

std::weak_ptr

std::auto_ptr

正则表达式

Lambda表达式

Lambda表达式语法定义

1
2
[捕获列表][参数列表][可变规则][返回类型][函数体]
[capture list] (parameters) mutable throw() -> return-type { statement }

Lambda捕获列表

类型 表达式
不捕获任何变量 []
值传递方式捕获变量var [var]
值传递方式捕获所有父作用域的变量,包括this [=]
引用传递方式捕获变量var [&var]
引用传递方式捕获所有父作用域的变量,包括this [&]
值传递方式捕捉当前的this指针 [this]

Lambda参数列表

Lambda可变规则

C++14 新特性

文件输入输出

按行读取txt文件内容

TXT文件内容如下:

1
2
3
4
Panda 26
Pikachu 27
Koala 25
Penguin 22

程序源代码如下:

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
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main(int argc,char **argv)
{
// ifstream fin("roster.txt", ios::in);
ifstream fin;
fin.open("roster.txt");

if (fin) {
string line;
while (getline(fin, line)) {
cout<<line<<endl;
stringstream word(line); // 以空格作为分割符
string name;
string age;
word>>name;
word>>age;
cout<<"name: "<<name<<" age: "<<age<<endl;
}
} else {
cout<<"The file can not be opened!"<<endl;
}

fin.clear();
fin.close();
system("pause");
return 0;
}

程序运行结果:

1
2
3
4
5
6
7
8
Panda 26
name: Panda age: 26
Pikachu 27
name: Pikachu age: 27
Koala 25
name: Koala age: 25
Penguin 22
name: Penguin age: 22