C++——从基础到Boost使用

目录

一、前言

二、C++ 基础

2.1 源文件

2.2 头文件

2.3 CmakeLists

三、C++ STL

3.1 模板文件

3.2 STL源文件

四、Boost Hello world

五、Boost 常用库使用


一、前言

C++学过很多遍了,不用总是忘,知识基础运用,通过运用可以很快了解如何使用

二、C++ 基础

俗话说得好,空谈误国,实干兴邦,便回顾便实战可以随时验证所学,融会贯通

2.1 源文件

humanbeing.cpp

#include <iostream>
#include "humanbeing.hpp"

HUM::Brain::Brain(int sec,int think):m_secret(sec),m_think(think)
{
    //this 指向当前对象,它是成员函数的一个形参,在调用成员函数时将对象的地址作为实参传递给 this
    std::cout<<"m_secret:"<< m_secret <<std::endl;
    this->m_cal = this->m_secret+m_think;
}

HUM::Brain::~Brain(){
    float image  =  12.7654321;
    /*强制类型转换:
    static_cast 不能用于无关类型之间的转换,如不同的类型指针,数据存储格式不一样
    const_cast用于去掉 const 和 volatile 修饰
    reinterpret_cast 高风险,补充static_cast,如具体类型指针转换
    dynamic_cast 类继承之间类型转换,向上向下均可
    */
    m_think = static_cast<int>(image);
    std::cout.precision(3);
    std::cout<<"I'm not gonna think: "<< image <<std::endl;
}

int HUM::Brain::add (int a,int b)
{
    return a+b;
}

void HUM::Brain::why(int a ,int b,int c)
{
    if(this->add(a,b) == c)
    {
        std::cout<<"you are celver:"<< add(a,b) <<std::endl;
    }
    else
    {
        std::cerr<<"you are stupid:"<< add(a,b) << std::endl;
    }
}
/*引用*/
void HUM::Brain::swap(int &a, int &b)
{
    std::cout<<"before a:"<< a <<" b:" << b << std::endl;
    int tem = b;
    b = a;
    a = tem;
}
void HUM::Brain::pstrTrans(Brain* &pbr)
{
    std::cout<<"&引用传指针* m_think:"<< pbr->m_think << std::endl;
}

/*const 在前修饰返回值,在后修饰成员函数针对成员变量; const对象只能访问const成员;*/
int HUM::Brain::getMySecret() const
{
    std::cout<<"my secret: "<< m_secret << std::endl;
    return this->m_secret;
}

void HUM::Brain::staticThinking()
{
    std::cout<<"I need "<< HUM::Brain::ms_area <<" hours to thinking"<< std::endl;
}

//友元
void HUM::freeFunc(Brain* pBrn)
{
    std::cout<<"I'm your friend,your sceret is "<<pBrn->m_secret<<std::endl;
}


void HUM::Brain::introduceFriends(Animal* pani)
{
    std::cout<<"My friends have legs "<<pani->m_leg <<std::endl;
}

void  HUM::Brain::getFriendsDetail(Animal* pani)
{
    std::cout<<"My friends have child "<<pani->m_children <<std::endl;
}

male.cpp

#include "male.hpp"
#include <iostream>


HUM::Male::Male(int sec,int think,int age):Brain(sec,think),m_age(age)
{
    std::cout<<" Male 类 构造"<<std::endl;
}

nature.cpp

#include <iostream>
#include "nature.hpp"

HUM::Animal::Animal(int legs):m_leg(legs)
{
    m_children = 3;
    std::cout<<"the animal have legs " <<m_leg<<std::endl;
}

main.cpp

#include <iostream>
#include "humanbeing.hpp"
#include "nature.hpp"
#include "male.hpp"
#include <typeinfo>
int HUM::Brain::ms_area = 5;


int main(int argc,char*argv[]){
    int a = 6;
    int b = 2;
    char sumAB = 13;
    HUM::Brain *phb  = new HUM::Brain(3,4);
    std::cout<<"input a number:"<<std::endl;
    //std::cin.getline(&sumAB,5);
    std::cout<<"the a number is:"<< static_cast<int>(sumAB) <<std::endl;
    phb->why(phb->ms_area,7,static_cast<int>(sumAB));
    std::cout<<"think: "<<phb->m_think<<std::endl;
    std::cout<<"a+b = "<<phb->add(a,b)<<std::endl;
    phb->why(a,b);
    phb->swap(a,b);//引用
    phb->pstrTrans(phb);
    std::cout<<"after a:"<< a <<" b:" << b << std::endl;
    phb->getMySecret();
    HUM::Brain::staticThinking();
    //友元
    HUM::freeFunc(phb);
    HUM::Animal dog(7);
    phb->introduceFriends(&dog);
    phb->getFriendsDetail(&dog);
    delete phb;
    //继承
    int age = 18;
    HUM::Male boy(a,b,age);
    boy.Brain::getMySecret();//子类访问基类的方法
    //typeid使用方法
    //获取一个字面量的类型信息
    const type_info& dInfo = typeid(25.65);
    std::cout << dInfo.name() << " | " << dInfo.raw_name() << " | " << dInfo.hash_code() << std::endl;
    //流
    //输出单个字符,ASCII码 put
    std::cout.put(71).put(79).put(79).put(68).put('\n');
    //向输出缓冲区添加指定字符串 write
    std::cout.write("http://", 7).write("c.biancheng.net", 15).write("/cplus/", 7).write("\r\n",4);
    //tellp seekp 读取或修改位于输出缓冲区的数据

    return 0;
}



2.2 头文件

humanbeing,hpp

#ifndef HUMANBEING
#define HUMANBEING 1
#include "nature.hpp"
class Animal;
namespace HUM{
    class Brain{//默认成员都是private, struct默认是public
        public:/*都可以访问*/
        int m_think;
        int m_cal;
        int m_rat;
        
        public:/*静态变量:实现多个对象共享数据的目标,类或者对象访问*/
        static int ms_area;

        private:/*成员函数中访问,子类、类外不能访问*/
        int m_secret;

        protected:/*子类、成员函数都可以访问,类外无法访问*/
            int m_littleBrain;

        public:
        Brain(int sec,int think);
        ~Brain();
        int add (int a,int b);/*类内的成员函数可以相互调用,访问*/
        void why(int a ,int b,int c = 8);
        void swap(int &a, int &b);/*引用传参: 数据别名*/
        void pstrTrans(Brain* &pbr);/*引用传递对象指针类型*/
        /*int& q[10] ;//q首先向右结合,所以这个相当于 (int&)q[] q是个数组,其中的元素是引用,叫引用的数组
        int(&p)[10] ;p首先和&结合,所以p是引用,引用的对象是数组,叫作数组的引用
        */
        public:
        int getMySecret() const;/*const 修饰成员函数,不能改变成员的值*/

        public: /*静态成员函数只能访问静态成员(没有this指针),类直接调用*/   
        static void staticThinking();

        public:/*友元函数可以独立,也可以是其他类成员函数,友元函数可以访问类所有成员*/
        friend void freeFunc(Brain* pBrn);
        /*两个文件的友元函数要相互添加.hpp文件*/
        void introduceFriends(Animal* pani);

        void getFriendsDetail(Animal* pani);

        };

        void freeFunc(Brain* pBrn);
}
#endif

male.hpp

#ifndef MALE
#define MALE 1
#include "humanbeing.hpp"

namespace HUM{
    class Male : public Brain
    {
        public:
        int m_age;
        int m_height;
        int m_weight;
        using Brain::m_littleBrain;//protected 权限改为 public
        public:
        /*对任意一个类,默认的构造函数,拷贝构造函数,析构函数如下:
        1 A(void); // 缺省的无参数构造函数
        // 缺省的拷贝构造函数,只有单个形参,形参为对本类类型对象的引用(用const修饰)
        //拷贝是在 【初始化】 阶段(类A a2 = a1)进行的,非初始化阶段赋值调用重载运算符=
        //也就是用其它对象的数据来初始化新对象的内存,针对有指针类型变量的类
        2 A(const A &a);
        3 ~A(void); // 缺省的析构函数
        4 A & operate =(const A &a); // 缺省的赋值函数
        */
        Male(int sec,int think,int age);
        /*派生类如果有与基类同名的函数,则回覆盖基类的函数,使用自己的函数
        */
        /*虚继承可以解决菱形问题A->B , A-> C  , B C ->D, 比如iostream 是从istream 和ostream继承得来,它俩从base_ios继承
        * 虚继承可以保留一份虚基类的成员,不回产生二义性。
        * 强制类型转换,遵循向上转型,转型后只能访问基类继承的成员
        */
        /*虚函数:基类指针只能访问派生类成员变量,不能访问派生类成员函数
        * 基类指针指向基类就访问基类成员,指向派生类就访问派生类,现象叫多态
        */
        /*纯虚函数:virtual 返回值类型 函数名 (函数参数) = 0;
        * 纯虚函数的类叫抽象类,抽象类是类型,让派生类实现纯虚函数
        */
    };
}

#endif

nature.hpp

#ifndef NATURE
#define NATURE 1
#include "humanbeing.hpp"
namespace HUM{
    class Animal
    {
        public:
        int m_leg;
        public:
        friend class Brain;//友元类
        private:
        int m_children;
        public:
        Animal(int legs);

        friend void introduceFriends(Animal* pani);//友元函数
    };

}
#endif

2.3 CmakeLists

cmake_minimum_required(VERSION 3.0)

project(reviewcpp
    VERSION 1.0
    DESCRIPTION "know how to use cmake"
    #LANGUAGES CXX #指定编程语言为CPP, 默认是CXX C
)

#add
aux_source_directory(./src SRC_DIR)
include_directories(./inc)
#exe
add_executable(cpprun ${SRC_DIR})

三、C++ STL

stand template library标准模板库通过模板实现了常用的数据结构算法,做到了算法和数据结构的分离。vector 的底层为顺序表(数组),list 的底层为双向链表,deque 的底层为循环队列,set 的底层为红黑树,hash_set 的底层为哈希表

3.1 模板文件

tempt.hpp中定义

#ifndef TMPT
#define TMPT
//函数模板
/*
template <class 形参名,class 形参名,......> 返回类型 函数名(参数列表)
{
    函数体
}
template <class T> void swap(T& a, T& b){},
*/
//类模板
/*
template<class  形参名,class 形参名,…>   class 类名
{ ... };
template<class T> class A{public: T a; T b; T hy(T c, T &d);};
template<class T1,class T2> void A<T1,T2>::h(){};
*/
template<class T> 
class Aba{
    public:
        T g(T a,T b);
        Aba();
};

#endif

3.2 STL源文件

/*
迭代器(指针):运用泛型技术隐藏不同容器内部差异,实现统一接口传送数据,遍历读写数据
输入迭代器,输出迭代器,前向迭代器fd,双向迭代器dd,随机访问迭代器rd
stack和queue不支持迭代器
容器类名::iterator 迭代器名; 常量正向迭代器const_iterator,反向迭代器 reverse_itertor,常量反向迭代器const_reverse_iterator
*/
/*
序列容器:
array ,长度固定不变
vector(rd),长度可变,尾部增加或删除元素效率高
deque(rd),支持高效尾部头部增加删除元素
list(dd),可变,任何地方增加删除元素高效,访问元素比前3个慢
forward_list, 正向链表,类似list,访问只能从第一个开始,比list块、节省内存
关联容器<key,value>:排序容器(从小到大)set(dd),multiset,map(dd),multimap;快速查找、读取删除,插入元素效率高于序列容器
哈希容器unordered_set(fd),unordered_multiset(fd),unordered_map(fd),unordered_multimap(fd)
*/
#include <iostream>
#include <array>
#include <vector>
#include <map>
#include "tmpt.hpp"
#include <deque>
#include <list>
#include <forward_list>
#include <iterator>
#include <utility>
#include <string>
#include <map>
#include <functional> //std::greater ,std::less
#include <set>
#include <unordered_map>
#include <stack>
#include <queue>//priority_queue
#include <algorithm>
#include <unordered_set>
using uint_t = unsigned int;
using map_int_t  = std::map<std::string,int>;
using func_t = void(*)(int,int); //typedef void(*func_t)(int,int)

template<class T> class A{
    public:
        T g(T a,T b){return a+b;}
        A(){std::cout<< "tem a out" <<std::endl;}
};
//tmpt.hpp
template<class T> Aba<T>::Aba(){std::cout<< "tem a out" <<std::endl;}
 
template<class T> T Aba<T>::g(T a,T b)
{
    return a+b;
}

class CopyReg{
    public:
        bool operator()(const int& i)
        {
            return(i%2==1);
        }
};

int main(int argc,char* argv[])
{
    //template
    Aba<int> a;
    std::cout<< "template call:"<<a.g(2,3) <<std::endl;
    int i = 0;
    //----------- array -------------------
    std::array<double,10> box;//不能用push_back
    //std::array<double,10>::iterator ibox;
    for(auto ibox = box.begin();ibox!=box.end();ibox++,i++)
    {
        box[i] = i;
        //std::cout<<box.at(i)<<std::endl;//box[i]
        //std::cout<< *ibox <<std::endl;
        box.at(i)+=3;//at避免越界访问
    }
    for(auto& v :box )//每一个元素的引用
    {
        v = v+1;
        //std::cout<< "v: "<< v <<std::endl;
    }
    box.fill(7.7);//填充所有元素
    std::cout<<"box back: "<<box.back()<<std::endl;//front
    std::cout<<"box length: "<<box.size()<<std::endl;
    auto first_it = box.begin();
    auto last_it = box.end();
    while(first_it !=last_it)
    {
        *first_it = i;
        //std::cout<< *first_it <<std::endl;
        ++first_it;
        i++;
    }
    //----------- vector -------------------
    std::vector<uint_t> vec(10,0);
    std::vector<uint_t> vct;
    for(auto i = 0;i<5;i++)
        vct.push_back(i);//从队尾追加,先创建再拷贝或移动到容器中
    for(auto i = 0;i<5;i++)
        vct.emplace_back(i);//从队尾追加,直接在容器尾部创建元素,优先使用emplace_back
    //删除
    vct.pop_back();//队尾删除
    vct.erase(vct.begin()+3);
    std::cout<<"befor :"<<vct.capacity()<<std::endl;
    vct.shrink_to_fit();//将内存减少到等于当前元素实际所使用大小
    std::cout<<"after :"<<vct.capacity()<<std::endl;
    std::swap(vec,vct);
    vec.at(2) = 77;//支持防止越界访问at
    vec.insert(vec.begin()+2,3);//第一个参数是迭代器,insert支持插入容器和多个元素
    vec.emplace(vec.end()-2,7);//emplace只允许一次插入一个元素,而不是多个
    for(auto &v : vec)//每个元素引用
    {
        v+=2;
        //std::cout<< "v:vec "<<v<<std::endl;
    }
    std::cout<< "vec:front "<<vec.front()<<std::endl;//队头, back()队尾
    vec.clear();
    vct.clear();//移出所有元素,大小为0
    //----------- deque -------------------double ended queue: 不保证所有元素存储连续空间中;remove所有相等元素
    std::array<int,5> ar{1,2,3,4,5};
    std::deque<int> dq(ar.begin()+2,ar.end());
    dq.pop_back();
    dq.pop_front();
    dq.push_back(7);
    dq.push_front(8);
    for(auto& d: dq)
    {
        //std::cout<< "d:dq "<< d <<std::endl;
    }
    dq.clear();
    //----------- list  -------------------双向列表,两端可以快速删除插入,访问元素慢
    /*
    remove_if:删除满足条件的元素
    unique:删除相邻重复元素,只保留一个
    merge:合并已排序list容器
    sort:排序(默认从小到大)
    */
    std::list<int> vlist(3,6);
    vlist.push_back(7);
    for(std::list<int>::iterator it = vlist.begin();it !=vlist.end();it++)
    {
        //std::cout<< "L:list "<< *it <<std::endl;
    }
    vlist.clear();
    //----------- forward list -------------------高效的list,前向链表,不提供size()
    std::forward_list<int> vFL(3);
    vFL.push_front(1);
    vFL.push_front(11);
    vFL.push_front(111);
    int vfsize = std::distance(std::begin(vFL),std::end(vFL));
    std::cout<< "FL:list size "<< vfsize <<std::endl;
    auto it = vFL.begin();
    advance(it, 1);//移动迭代器
    while (it!=vFL.end())
    {
        std::cout << *it << " ";
        ++it;
    }
    vFL.clear();
    //----------- pair-------------------#include <utility> 键值对,<first, second>
    //make_pair返回一个pair对象,是一个临时对象,右值引用 调用移动构造函数
    std::pair <std::string, std::string> pair1(std::make_pair("C++", "http://c.biancheng.net/cplus/"));
    std::pair<std::string,std::string>   pair2 = std::make_pair("C++", "hello world");
    std::cout << "pair2: " << pair2.first << " " << pair2.second << std::endl;
    //----------- map-------------------
    /*
    键是唯一的;根据键大小进行排序,
    默认std::less<T>;设置为std::greater<T>
    map的元素是pair类对象;
    lower_bound(key)不小于key的键值对迭代器
    upper_bound(key)大于key的键值对迭代器
    */
    std::map<std::string, int,std::greater<std::string> > myMap;
    myMap.emplace("job1",8500);
    myMap.emplace("job2",20000);
    myMap.emplace("job3",16000);
    if(!myMap.empty())
    {
        for(auto it = myMap.begin();it != myMap.end();it++)
        {
            std::cout<<it->first<<" "<<it->second<<std::endl;
        }
    }
    // multimap 键可以重复
    //----------- set -------------------
    /*
    键值完全相同,值不能重复,根据键大小进行排序
    修改元素的方法,先删除,再添加
    */
    std::set<std::string> myset{"http://c.biancheng.net/java/","http://c.biancheng.net/stl/"};
    myset.insert("http://c.biancheng.net/python/");
    for(auto it = myset.begin();it!=myset.end();it++)
        std::cout<< *it <<std::endl;
    //multiset 值可以重复
     //----------- unordered_map -------------------
    /*无序容器内部存储的键值对是无序的,各键值对的存储位置取决于该键值对中的键
      无序容器擅长通过指定键查找对应的值,不擅长遍历容器
      不会对键值对排序
    */
    std::unordered_map<std::string, std::string> my_uMap{
        {"C","http"} };
    auto itP2 = my_uMap.insert(pair2);
    //查找指定键对应的值,效率比关联式容器高
    std::string str = my_uMap.at("C");
    std::cout << "str = " << str << std::endl;
    //----------- 容器适配器 -------------------
    /*将不适用的转化为可用
    stack栈适配器:默认deque,满足条件vector,deque,list;单端口容器(栈顶),先进后出,push,pop,top,size
    queue队列适配器:默认deque,满足条件deque,list
    priority_queue优先权队列适配器:默认vector,满足条件vector,deque, First In Largest Out
    */
    std::list<int> temL{1,2,3};
    std::stack<int,std::list<int>> myStack(temL);
    while(!myStack.empty())
    {
        //std::cout<<myStack.top()<<std::endl;
        myStack.pop();
    }
    std::array<int,4> temA{ 4,1,3,2 };
    std::priority_queue<int>myPQ(temA.begin(),temA.end());//{4,2,3,1}
    while(!myPQ.empty())
    {
        std::cout << myPQ.top()<<" ";
        myPQ.pop();//移除队头元素的同时,将剩余元素中优先级最大的移至队头
    }
    //----------- 迭代器适配器 -------------------
    /*
    reverse_iterator:逆向迭代器 ++ --, 反向迭代器内部互换了 ++ 和 -- 
    insert_iterator:在容器任何位置添加新的元素
    istream_iterator:用于从文件或者键盘读取数据
    move_iterator:将某个范围的类对象移动到目标范围,而不需要通过拷贝移动
    */
    std::reverse_iterator<std::list<int>::iterator> rb = temL.rbegin();
    std::reverse_iterator<std::list<int>::iterator> re = temL.rend();
    while (rb != re) {
        std::cout << *rb << " ";
        ++rb;
    }
    //----------- 常用算法 -------------------
    /*http://c.biancheng.net/view/7493.html
    find_if:在容器中查找满足条件的元素迭代器索引
    search:在序列 A 中查找序列 B 第一次出现的位置
    binary_search:查找指定区域内是否包含某个目标元素,二分法
    copy_if:过滤器
    unique:可以在序列中原地移除重复的元素,常和std::erase搭配
    rotate:如何旋转序列
    transform:将函数应用到序列的元素上,并将这个函数返回的值保存到另一个序列中
    replace:用新的值来替换和给定值相匹配的元素
    */
    std::vector<int> vecG{4,2,3,1,5};
    std::vector<int>::iterator vit = std::find_if(vecG.begin(),vecG.end(),CopyReg());
    std::cout << "find_if: "<<*vit << std::endl;

    std::vector<std::string> names {"A1", "Beth", "Carol", "Dan", "Eve","Fred", "George", "Harry", "Iain", "Joe"};
    std::unordered_set<std::string> more_names {"Jean", "John"};
    size_t max_length{4};
    std::copy_if(std::begin(names), 
    std::end(names), 
    std::inserter(more_names, std::begin(more_names)),
    [max_length](const std::string& s) { return s.length() <= max_length;});
    
    return 0;
}

CMakeLists.txt与第二节使用的相同

四、Boost Hello world

五、Boost 常用库使用

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Boost C++库是一个提供了一系列高质量的、跨平台的C++库的开源社区项目。这个库提供了许多常用的C++功能和工具,可以帮助开发者更快、更高效地开发C++应用程序。 Boost库的版本分为两个主要分支:主线版(mainline)和LTS版(long-term support)。主线版是Boost库的最新版本,包含了最新的特性和更新。LTS版是长期支持版,提供了稳定的代码和向后兼容性,适合用于生产环境。 Boost库的版本号遵循着X.Y.Z的命名规则,其中X代表主版本号,Y代表次版本号,Z代表修订号。主版本号的增加通常表示了有较大的重大更改或不向后兼容的修改。次版本号的增加通常表示了有新的特性添加进来,而修订号的增加通常表示了有错误修复或较小的更新。 为了保持代码质量和稳定性,Boost社区使用了一套开发和发布流程。开发者可以从Boost的官方网站下载最新版本的Boost库,并且可以通过提交贡献来参与Boost库的开发。同时,Boost库也接受用户的Bug报告和功能请求,并在后续版本中进行修复或添加。 总之,Boost C++库是一个非常重要和受欢迎的C++开源项目,通过提供丰富的功能和工具,帮助开发者更轻松地进行C++应用程序的开发。无论是主线版还是LTS版,都能满足不同开发需求,并且通过持续的更新和贡献,Boost库能够不断优化和完善,提供更好的开发体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值