本文主要探讨c++相关知识。
static_cast:编译器认为安全的类型转换
const_cast:去掉常量属性且提过安全检查
reinterpret_cast:强制类型转换
dynamic_cast:主要用在继承结构,支持RTTI类型转换
dynamic_cast:将传入指针是否与转换类型相同,不同返回nullptr(转换失败),相同转换成功
class A{}; sizeof(A) = 1
class B :public A{};sizeof(B) = 1;
class A {virtual void fun(){};};
class B :public A{};sizeof(B) = 4;//vfptr(虚函数表)
class A {virtual void fun(){};};
class B :virtual public A{};sizeof(B) = 8;//vbptr(虚基类表)+vfptr(虚函数表)
基类指针指向派生类对象,永远指向派生类基类的起始地址
虚继承解决多继承(菱形)基类被多次继承问题
vector:动态开辟数组(连续)且二倍扩容
reserve(n)预分配n个元素,不初始化元素,capacity变为n,size不变,n小于当前容量不做改变
resize(n)调整容器大小为n,不足添加并初始化(默认构造),超过删除尾部元素
deque:动态开辟二维数组(第二维是定长连续空间,第二维间不连续),以2倍方式扩容(第一维2倍扩容)
vector和deque区别:vector底层是数组,deque是二位数组,首插deque是O(1),vector是O(n),中插和尾插均为O(1)
vector和list区别:list底层为双向循环链表
数组:增加删除O(n),查询O(n),随机访问O(1)
链表:增加删除O(1),查询O(n),随机访问O(n)
stack依赖deque实现,queue依赖deque实现,priority_queue依赖vector实现:
vector初始内存使用效率低(从1开始2倍扩容)deque起始为4096字节初始化
若queue用vector实现删除O(n),出队效率低
且vector需连续内存,deque只需分段内存
priority_queue底层是大根堆,大小根堆需要内存连续
无序关联容器增删查O(1),unordered_set为单重集合,unordered_multiset为多重集合
map映射表可用[]重载访问,key不存在会创建数据,unordered_map为单重映射表,unordered_multimap为多重映射表
有序关联容器(set,multiset,map,multimap)删查O(log2n)
函数对象通过重载函数调用操作符operator()实现可
demo1:
dynamic_cast ,const_cast
目录结构:
代码示例:
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 3.28) #最低版本要求
SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器
PROJECT(CLASS) #设置工程名
MESSAGE(STATUS "CPP test") #打印消息
ADD_EXECUTABLE(pro test.cpp) #生成可执行文件
run.sh
#!/bin/bash
if [ -f ./Makefile ]
then
make clean
fi
cmake .
make
echo "---------------------------------"
./pro
g++ test.cpp -o test -g
objdump -S test > test.dis
clean.sh
rm -rf CMakeCache.txt CMakeFiles Makefile cmake_install.cmake *.o pro test test.dis
test.cpp
#include <iostream>
class C
{
public:
virtual void func() = 0;
};
class D : public C
{
public:
void func()
{
std::cout << "D::func()" << std::endl;
}
};
class E : public C
{
public:
void func()
{
std::cout << "E::func()" << std::endl;
}
};
static void ShowFunc(const C *c)
{
//const_cast:去掉const修饰
C* tmp = const_cast<C*>(c);
//dynamic_cast:将传入指针是否与转换类型相同,不同返回nullptr(转换失败),相同转换成功
D *d = dynamic_cast<D*>(tmp);
if(d != nullptr)
{
d->func();
}
else
{
E *e = dynamic_cast<E*>(tmp);
e->func();
}
}
int main()
{
D d;
E e;
ShowFunc(&d);
ShowFunc(&e);
return 0;
}
结果示例:
demo2:
map,unordered_multiset
目录结构:
代码示例:
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 3.28) #最低版本要求
SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器
PROJECT(CLASS) #设置工程名
MESSAGE(STATUS "CPP test") #打印消息
ADD_EXECUTABLE(pro test.cpp) #生成可执行文件
run.sh
#!/bin/bash
if [ -f ./Makefile ]
then
make clean
fi
cmake .
make
echo "---------------------------------"
./pro
g++ test.cpp -o test -g
objdump -S test > test.dis
clean.sh
rm -rf CMakeCache.txt CMakeFiles Makefile cmake_install.cmake *.o pro test test.dis
test.cpp
#include <iostream>
#include <unordered_set>
#include <map>
#include <algorithm>
int main()
{
std::unordered_multiset<int> Set;
std::map<int,int> Map;
for(auto i = 0; i < 20; i++)
{
Set.insert(rand()%100);
}
for(auto s = Set.begin();s != Set.end();s++)
{
if(auto m = Map.find(*s); m != Map.end())
m->second++;
else
Map.insert({*s,1});
}
for_each(Map.begin(),Map.end(),
[](const std::pair<int,int>& n)
{
std::cout << n.first << ":" << n.second << std::endl;
});
return 0;
}
结果示例: