枚举
enum CarType {
CarTypeLit, CarTypeMiddle, CarTypeLitBig
};
CarType type = CarTypeMiddle;
cout << type << endl;
// 强类型枚举
- 强类型枚举
enum class CarType2 {
LitCar, MiddleCar=10, BigCar
};
CarType2 type2 = CarType2::MiddleCar;
cout << (type2 == CarType2::MiddleCar) << endl;
默认情况下,枚举的基本类型是整型,可以采用如下方式修改类型
enum class CarType2 : unsigned long {
LitCar, MiddleCar=10, BigCar
};
CarType2 type2 = CarType2::MiddleCar;
cout << (type2 == CarType2::MiddleCar) << endl;
结构体
struct Person
{
int age;
char *name;
};
Person per = {100, "admin"};
cout << per.name << endl;
数组
- 将所有元素声明为 : 0
int arr[3] = {0};
- 将其他元素声明为: 0
int arr[3] = {2};
- 二维数组
int arr[3][3] = {{1,2}};
1,2,0
0,0,0
0,0,0
简写
int arr[][2] = {{1,2}, {3,4}};
std::array
c++容器<array>
,结构体
#include <iostream>
#include <array>
using namespace std;
std::array<int, 3> arr = {2,35,7};
cout << arr.size() << endl; // 3
cout << arr[1] << endl; // 35
c风格和C++风格的数组都是在定义时确定长度,不可以扩容
函数
每个函数内部都有一个静态变量 __func__
static const char __func__[] = "function name"
替代的函数语法( auto fun() -> int)
拖尾返回类型,在函数模板返回类型非常有用。
auto add(int a, int b)->int
{
return a + b;
}
函数返回类型的推断
auto add(int a, int b)
{
return a + b;
}
类型推断
auto
- 编译时自动推断变量的类型
auto a = 123; // will be int
decltype
把表达式作为参数,从而计算出类型
int x = 123;
decltype(x) y = 100; // y will be int
引用
int *n = new int;
*n = 200; // 间接引用
cout << *n << endl;
delete n;
n = nullptr;
在间接引用的指针必须有效,否则可能造成程序崩溃
- 让指针指向变量的地址
int a = 200;
int *b = &a; // *b <==> a
- 指向结构的指针,结构指针
Person *per = new Person;
per->name = "admin";
cout << per->name << endl;
delete per;
per = nullptr;
- 引用传递参数
void swap(int &a, int &b)
{
int c = a;
a = b;
b = c;
}
动态分配数组
const int len = 10;
int *arr = new int[len];
arr[0] = 200;
cout << arr[0] << endl; // 200
delete[] arr;
指针后移:
const int len = 10;
int *arr = new int[len];
arr[0] = 200;
arr[1] = 300;
cout << *arr << endl; // 200
arr++;
cout << *arr << endl; // 300
delete[] arr;
每次使用new [] 都必须对应的有delete[],每次有new 必须有delete
NULL是空指针常量,不是指针。NULL等价于0
void fun1(char *str)
{
}
void fun1(int a)
{
}
fun1(NULL); // 调用int a
fun1(nullptr); // 调用char * str
智能指针
智能指针在超出作用范围后,自动释放空间。
<memory>
- unique_ptr
auto per = std::make_unique<Person>();
尖括号必须指定指向的内存类型
-
shared_ptr允许数据的分布式“所有权”。每次指定shared_ptr时,都递增一个引用计数,指出数据有多了一个“拥有者”。shared_ptr超出作用范围时,会将引用计数减一。当引用计数为零时,标识改数据没有拥有者,于是释放资源。
-
使用weak_ptr可以观察shared_ptr
auto_ptr已经别废弃
异常处理
int devide(int i, int j)
{
if (j == 0)
{
throw std::invalid_argument("除数不能为零...");
}
return i/j;
}
try
{
int i = devide(10, 0);
}
catch (const std::exception &exception)
{
cout << exception.what() << endl; //除数不能为零...
}
const引用
const使程序不能修改变量,引用为了修改变量,看似冲突。实际上const&可以提高参数传递的效率,使用值引用会复制一个副本。在处理对象时,const引用会变得非常重要。
decltype(auto)
const string message = "test";
const string& foo()
{
return message;
}
- 使用auto接收
auto msg1 = foo();
cout << (&msg1 == &message) << endl; // 0
decltype(auto) msg2 = foo();
cout << (&msg2 == &message) << endl; // 1
- decltype(foo()) 等价于 const string& msg 2 = foo();
简写: decltype(auto) msg2 = foo();
类
员工管理
- 头文件
#pragma once
#include <string>
namespace Records
{
const int kDefaultStartingSalary = 30000;
class Employee
{
public:
Employee();
// 涨工资
void promote(int raiseSalary = 10000);
void demote(int reduceSalary = 1000);
void hire();
void fire();
void display();
const std::string &getMFirstName() const;
void setMFirstName(const std::string &mFirstName);
const std::string &getMLastName() const;
void setMLastName(const std::string &mLastName);
int getMEmployeeNumber() const;
void setMEmployeeNumber(int mEmployeeNumber);
int getMSalary() const;
void setMSalary(int mSalary);
bool isMHired() const;
void setMHired(bool mHired);
private:
std::string mFirstName;
std::string mLastName;
int mEmployeeNumber;
int mSalary;
bool mHired;
};
}
- 实现
#include <iostream>
#include "Employee.h"
using namespace std;
namespace Records
{
Employee::Employee()
: mFirstName("Mr."), mLastName("G."), mSalary(kDefaultStartingSalary), mEmployeeNumber(1), mHired(false)
{
cout << mSalary << endl;
}
void Employee::promote(int raiseSalary)
{
this->setMSalary(getMSalary() + raiseSalary);
}
void Employee::demote(int reduceSalary)
{
setMSalary(getMSalary() - reduceSalary);
}
void Employee::hire()
{
mHired = true;
}
void Employee::fire()
{
mHired = false;
}
void Employee::display()
{
cout << "Employee: " << getMLastName() << "," << getMFirstName() << endl;
cout << "------------" << endl;
cout << (mHired ? "被解雇了" : "在职") << endl;
cout << "工号:" << mEmployeeNumber << endl;
cout << "工资:" << mSalary << endl;
cout << endl;
}
// getter and setter
const string &Employee::getMFirstName() const
{
return mFirstName;
}
void Employee::setMFirstName(const string &mFirstName)
{
Employee::mFirstName = mFirstName;
}
const string &Employee::getMLastName() const
{
return mLastName;
}
void Employee::setMLastName(const string &mLastName)
{
Employee::mLastName = mLastName;
}
int Employee::getMEmployeeNumber() const
{
return mEmployeeNumber;
}
void Employee::setMEmployeeNumber(int mEmployeeNumber)
{
Employee::mEmployeeNumber = mEmployeeNumber;
}
int Employee::getMSalary() const
{
return mSalary;
}
void Employee::setMSalary(int mSalary)
{
Employee::mSalary = mSalary;
}
bool Employee::isMHired() const
{
return mHired;
}
void Employee::setMHired(bool mHired)
{
Employee::mHired = mHired;
}
}