C++高级用法简单应用及docker的使用技巧

news/2024/11/18 0:28:20/
  1. //std::move的移动构造函数的简单使用;
    #include
    using namespace std;

int main()
{
std::string str(“hello”);
std::vectorstd::string strvec;
strvec.push_back(str);
cout<<str<<endl;
strvec.push_back(std::move(str)); //调用std::move移动构造函数,掏空str,掏空后,最好不要用str;
cout<<str<<endl; //输出为""
cout<<strvec[0]<<" "<<strvec[1]<<endl;
return 0;
}

2)函数模板的具体化应用案例;
#include
using namespace std;

void handle(int a)
{
cout<<"普通函数 "<<a<<endl;
}

template
void handle (T a)
{
cout<<"模板函数 "<<a<<endl;
}

template<>
void handle(double a)
{
cout<<"函数模板的具体化 "<<a<<endl;
}

int main()
{
handle(3);
handle(5);
handle(67.68);
return 0;
}

3)随机数的使用:
#include
#include <stdlib.h>

using namespace std;

int main()
{
srand((unsigned)time(0));
cout<<rand() % 10<<endl;
cout<<rand() % 10<<endl;
cout<<rand() % 10<<endl;
return 0;
}

4)设置输出精度的案例:
#include
#include
using namespace std;

int main()
{
cout<<cout.precision()<<endl; //返回当前精度值,默认输出6
cout.precision(12); //设置当前精度值
double a = 4.6644332211;
cout<<a<<endl;
return 0;
}

5)命名空间的使用
using Test::add; //打开包裹,拿出一个名称,叫做"声明";
using namespace Test; //打开包裹,拿出所有内容,叫做"指示";
//命名空间可以是不连续的,在头文件时,创建命名空间(创建包裹)
namespace Test
{
int add(int a,int b); //声明
}

namespace Test //有同名的命名空间,往包裹内部添加内容;
{
int add(int a,int b) //定义
{
return a + b;
}
}

int main()
{
cout<<Test::add(3,4)<<endl;
return 0;
}

6)重载new和delete操作符,内部利用的是malloc和free函数;
#include
#include

using namespace std;

void* operator new(size_t size)
{
cout<<"operator new : "<<size <<endl;
auto p = malloc(size);
if(!p)
{
throw std::bad_alloc();
}
return p;
}

void* operator new[](size_t size)
{
cout<<"operator new[] : "<<size <<endl;
auto p = malloc(size);
if(!p)
{
throw std::bad_alloc();
}
return p;
}

void operator delete(void* ptr)
{
cout<<“operator delete–”<<endl;
std::free(ptr);
}

void operator delete[](void* ptr)
{
cout<<“operator delete[]–”<<endl;
std::free(ptr);
}

class TestMem
{
public:
int a = 0;
TestMem()
{
cout<<“create memory–”<<endl;
}
~TestMem()
{
cout<<“decreate memory------”<<endl;
}
};

int main()
{
auto mem1 = new TestMem();
delete mem1;

int* arr1 = new int[1024];
delete[] arr1;auto mem2 = new TestMem[2];
delete[] mem2;return 0;

}

7)指针的应用
int* ptr = new int;
delete ptr;
ptr = nullptr; //没有这句话,如果再次执行delete ptr的话,会出现错误,如“free(): double free detected in tcache 2”
堆区和栈区是相对申请空间的,堆区是从低到高,栈区是从高到低;

8)不要在构造函数和析构函数中调用virtual函数,案例如下:
#include
#include
#include

using namespace std;

class Base
{
public:
Base(){sayHello(); }
virtual void sayHello()
{
cout<<“hello base constructor—”<<endl;
}
virtual void sayBye()
{
cout<<“sayBye base deconstructor—”<<endl;
}
~Base(){sayBye(); }
};

class Derived : public Base
{
public:
Derived(){}
void sayHello()override
{
cout<<“hello Derived constructor—”<<endl;
}
void sayBye()override
{
cout<<“sayBye Derived deconstructor—”<<endl;
}
};

int main()
{
Derived derived;
return 0;
}
输出情况:
hello base constructor—
sayBye base deconstructor—

9)条款10:operator=,operator+=等运算符重载,返回的是自身引用;

10)std::shared_ptr的用法:
shared_ptr myclone(int p)
{
// return new int§; //错误,隐式转换为shared_ptr
return shared_ptr(new int§); //必须显示的创建shared_ptr;
}

int main()
{
std::shared_ptr ptr = make_shared(42);
auto ptr1(ptr);
std::shared_ptr p5(new int(55));
return 0;
}

10)explicit在构造函数中的使用,代码如下:
class MyClass
{
public:
explicit MyClass(int num)
{
number=num;
}

private:
int number;

};

int main()
{
//如果构造函数中,添加关键字explicit,则下面这句代码是错误的,只能MyClass obj(10);
// MyClass obj=10; //ok, convert int to MyClass //做了隐式转换,实际是下面两句代码的执行过程;
// MyClass temp(10);
// MyClass obj = temp;
MyClass obj(10);
return 0;
}

11)详细的介绍delete[] 为什么里面不用写数字,代码如下:先转换为void**,再转换为size_t*;
int main()
{
std::string* ptr = new std::string[20];
using add_t = void*;
auto len = reinterpret_cast<size_t*>(reinterpret_cast<add_t*>(ptr) - 1);
cout<<"len: "<<*(len)<<endl;
delete[] ptr;

return 0;

}

12)非常清楚,在函数调用完成后,何时返回引用,何时返回值;

13)查看类型推导的结果
#include
#include
#include
#include

using namespace std;
template
void f(const T& param)
{
cout<<typeid(T).name()<<endl;
cout<<typeid(param).name()<<endl;
}

class Mywidget
{

};

std::vector createVec() //工厂模式
{
return {Mywidget{}};
}

int main()
{
const auto tmp = createVec();
if(!tmp.empty())
{
f(&tmp[0]);
}
return 0;
}

14)单例模式的简单应用1
#include
#include
#include
#include

using namespace std;
//单例模式三要素:定义私有构造函数,定义一个私有的静态实例,定义一个共有的获取实例的静态方法;
// (static静态成员数据) (static 静态成员函数)
class A
{
private:
A():m_name(“A”){cout<<“a constructor is handle”<<endl;}
~A(){ cout<<“a deconstructor is handle—”<<endl;}
A(const A& obj) = delete;
A& operator=(const A& obj) = delete;
static A* m_instance;
string m_name;
public:
static A* instance(void)
{
if(m_instance == nullptr)
{
m_instance = new A();
}
return m_instance;
}
void show(void)
{
cout<<m_name<<endl;
}
};
A* A::m_instance = nullptr; //静态数据
int main()
{
A::instance()->show();
return 0;
}

15)单例模式的模板类应用案例,包括了友元类的使用
#include
#include

using namespace std;

namespace Tool
{
template
class singleTon
{
public:
static T* instance()
{
if(instance_ == nullptr)
{
instance_ = new T();
}
return instance_;
}
private:
singleTon(){}
~singleTon(){}
singleTon(const singleTon& ) = delete;
singleTon& operator=(const singleTon)=delete;
private:
static T* instance_;
};

template
T* singleTon::instance_ = nullptr;
};

using namespace Tool;

class A
{
public:
friend class singleTon;
public:
void show(void)
{
cout<<m_name<<endl;
}
private:
A():m_name(“A”){cout<<“a constructor is handle”<<endl;}
~A(){ cout<<“a deconstructor is handle—”<<endl;}
A(const A& obj) = delete;
A& operator=(const A& obj) = delete;
private:
string m_name;
};

int main()
{
//单例模式在多线程安全访问的安全机制:在主线程创建,在子线程访问即可
using namespace Tool;
singleTon::instance(); //创建
singleTon::instance()->show(); //访问
return 0;
}

16)std::bind的参数绑定函数使用方法
int test(int a,int b,int c)
{
cout<<a<<b<<c<<endl;
return 0;
}

int main()
{
auto a = std::bind(test,1,2,3); //函数体和参数相绑定,成为一个新的函数体;
a();
return 0;
}

第二种写法:
int test(int a,int b,int c)
{
cout<<a<<b<<c<<endl;
return 0;
}

int main()
{
auto a = std::bind(test,1,std::placeholders::_1,std::placeholders::_2); //函数体和参数相绑定,成为一个新的函数体;
a(56,78);
return 0;
}

17)在C++中,using的三种使用方法:引入命名空间,定义类型别名,在派生类中引用基类成员;
using vectorType = std::vector; //用using定义类型别名

int main()
{
vectorType v1;
v1.push_back(23);
return 0;
}

(一)解压同事白晓明的env_sdk_2.4.1的sdk,把文件拷贝到如下docker(keen_meitner)文件夹下,注意拷贝到docker容器是跟目录,和原生的sdk不是一个目录!!!
docker cp env_sdk_2.4.1 keen_meitner:/
(二)进入keen_meitner docker容器:
docker exec -it keen_meitner /bin/bash

(三)在docker根目录下,find -name ti-cgt-c7000_2.0.1.STS,查找文件,输出结果如下:
./opt/autobrain/sysroot/toolschain/ti-cgt-c7000_2.0.1.STS
(四)更改编译选项:
1)在"vi tools/toolchain/toolchain_linux_a72.mk"文件下,更改TC_PATH_CC和TC_PATH_ROOTFS目录,如下所示(注意是toolschain):
TC_PATH_CC := /opt/autobrain/sysroot/toolschain/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin
TC_PATH_ROOTFS := /opt/autobrain/sysroot/toolschain/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc
2)在"vi tools/toolchain/toolchain_freertos_r5f.mk"文件下,更改TC_PATH_CC目录,如下所示(注意是toolschain):
TC_PATH_CC := /opt/autobrain/sysroot/toolschain/ti-cgt-armllvm_1.3.0.LTS
3)在"vi tools/toolchain/toolchain_freertos_c71.mk"文件下,更改TC_PATH_CC目录,如下所示(注意是toolschain):
TC_PATH_CC := /opt/autobrain/sysroot/toolschain/ti-cgt-c7000_2.0.1.STS

(五)在docker中,更改Makefile编译环境的方法:
1)进入/workspace/env_sdk_2.4.1/Libs目录下;
2)按ab_demo的编译格式更改,共计更改七处,如添加process17目标文件;
3)在/workspace/env_sdk_2.4.1/Libs目录下,输入make process17即可;
LIB-y += $(ROOTFS_DIR)/usr/lib64/libpthread.so

(六) 出现类似如“task.cpp:(.text._Z7AppRecvv+0x24c): undefined reference to `Osal_setCpuName’”的错误,是需要拷贝配置环境,方法如下:
用白晓明给的的那个环境拷贝:cp /workspace/env/cfg_env/scfg/buildcfg/process17/ /workspace/env_sdk_2.3.5/Libs/env/cfg_env/scfg/buildcfg -R
涂宁告诉的:cp env/cfg_env/scfg/buildcfg/ab_demo/ /env_sdk_2.4.1/Libs/env/cfg_env/scfg/buildcfg/ -R

(七)刘占山告诉的,需要添加编译配置文件,方法如下:
进入目录:“/workspace/env_sdk_2.3.5/Libs/env/cfg_env/scfg/buildcfg”,打开 vim scfg_buildlist.mk文件,添加如下语句:
SCFG_BUILD_LIST += process17.linux_a72.19^


http://www.ppmy.cn/news/749970.html

相关文章

Hadoop2.6分布式 automatic HA+Federation+Yarn教程

一、前言 与Hadoop1.x相比&#xff0c;Hadoop2.x中的NameNode不再是只有一个了&#xff0c;可以有多个&#xff08;目前只支持2个&#xff09;。每一个都有相同的职能。 这两个NameNode的地位如何哪&#xff1f; 答&#xff1a;一个是active状态的&#xff0c;一个是standby…

katago安装使用

看了今天柯洁和大申的比赛, AI还是太强了 本文介绍的是windows下如何配置 项目下载地址: https://github.com/lightvector/KataGo/releases 有显卡的推荐opencl版本, 作者推荐理由 OpenCL vs CUDA vs Eigen KataGo has three backends, OpenCL (GPU), CUDA (GPU), and Eigen…

围棋AI-KataGo安装记录

KataGo 项目地址: https://github.com/lightvector/KataGo/releases 计算平台选择 最新版本为 v1.8.2 有三种版本: OpenCL vs CUDA vs Eigen 项目说明中的描述如下 KataGo has three backends, OpenCL (GPU), CUDA (GPU), and Eigen (CPU). The quick summary is: Use Open…

java实现字符压缩算法

public class CompressionAlgorithm1 { /** * param args * 实现简易字符串压缩算法&#xff1a;一个长度最大为128的字符串&#xff0c; * 由字母a-z或者A-Z组成&#xff0c;将其中连续出现2次以上&#xff08;含2次&#xff09;的字母转换为字母和出现次数&#xff0c; * 以达…

oracle job调用shell,Oralce通过Java调用Shell 无响应解决方法

Oralce通过Java调用Shell 无响应 本帖最后由 loomz 于 2014-02-25 18:52:24 编辑 各位好&#xff1a; 我目前在做一个程序&#xff0c;Oracle存储过程通过Java(Java Sources)调用Shell脚本&#xff0c;试好其它方法&#xff0c;都没有成功。下面是我用通过java调用shell的代码&…

C++写的12306抢票软件

写在前面的话 每年逢年过节&#xff0c;一票难求读者肯定不陌生。这篇文章&#xff0c;我们带领读者从零实现一款12306刷票软件&#xff0c;其核心原理还是通过发送http请求模拟登录12306网站的购票的过程&#xff0c;最后买到票。 郑重申明一下&#xff1a;这里介绍的技术仅供…

OSChina 周六乱弹 —— 你一口我一口多咬一口是小狗

2019独角兽企业重金招聘Python工程师标准>>> Osc乱弹歌单&#xff08;2018&#xff09;请戳&#xff08;这里&#xff09; 【今日歌曲】 达尔文 &#xff1a;分享Roy Orbison的单曲《Shes a Mystery to Me》 《Shes a Mystery to Me》- Roy Orbison 手机党少年们想听…

快速学习爬虫

快速学习爬虫 爬虫简介爬虫快速入门12306快速爬取信息 爬虫简介 网络爬虫&#xff08;英语&#xff1a;web crawler&#xff09;&#xff0c;也叫网络蜘蛛&#xff08;spider&#xff09;&#xff0c;是一种用来自动浏览万维网的网络机器人。其目的一般为编纂网络索引。 爬虫快…