c++理解(五)

        本文主要探讨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;
}

结果示例:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值