构造
#include<iostream>
#include<list>
using namespace std;
class A
{
private:
int a;
int *buf;
public:
A(){//构造
a = 0;
buf = new int[100];
cout << "A" << endl;
}
~A(){//析构
if (buf != nullptr)
{
delete[]buf;
cout << "~A" << endl;
}
}
A(const A &tmp)//拷贝构造函数 //= delete;
{
if(this!=&tmp)//检查自己拷贝自己
{
this->a = tmp.a;
this->buf = new int[100];
cout << "copy A" << endl;
}
}
A( A &&tmp)//移动构造
{
cout << "move A" << endl;
this->a = tmp.a;
this->buf = tmp.buf;
tmp.buf = nullptr;
}
A& operator=(const A &temp)//赋值函数 // = delete;
{
this->a = temp.a;
this->buf = new int[100];
cout << "= A" << endl;
return *this;
}
A operator=( A &&temp)//移动赋值
{
cout << "move = A" << endl;
this->a = temp.a;
this->buf = temp.buf;
temp.buf = nullptr; // 置为空指针
return std::move(*this);//变量强制转右值
}
A copyA(A&a)
{
return std::move(a);
}
};
int main()
{
list<A> list_;
for (auto a : { 1, 2, 4 })
{
cout << "-------begin------" << endl << endl;
list_.push_back(A());
}
cout << "-------1------" << endl;
list_.clear();
cout << "-------2------" << endl;
{
A a;
A b = a;
const A c;
A d = c;
}
getc(stdin);
return 1;
}
输出
-------begin------
A
move A
-------begin------
A
move A
-------begin------
A
move A
-------1------
~A
~A
~A
-------2------
A
copy A
A
copy A
~A
~A
~A
~A
智能指针
#include<iostream>
#include<list>
#include<memory>
using namespace std;
int cnt = 0; //记录C的分配析构次数
class C
{
public:
int c;
public:
C(int aa) :c(aa)
{
cnt++;
cout << "C" << endl;
}
~C()
{
cnt--;
cout << "~C" << endl;
}
C(const C&)
{
cout << "C copy" << endl;
cnt++;
}
};
int a = 0; //记录B的分配析构次数
class B
{
public:
std::shared_ptr<C> buf = nullptr;
public:
B() {
buf = make_shared<C>(3);
cout << "B" << endl;
a++;
}
~B() {
if (buf != nullptr)
{
a--;
cout << "~B" << endl;
}
}
B(const B& tmp) //= delete;
{
this->buf = make_shared<C>(*tmp.buf);
a++;
cout << "copy B" << endl;
//return *this;
}
B(B&& tmp)
{
cout << "move B" << endl;
this->buf = tmp.buf;
tmp.buf = nullptr;
}
B& operator=(const B& temp)// = delete;
{
a++;
this->buf = make_shared<C>(*temp.buf);
cout << "= B" << endl;
return *this;
}
B&& operator=(B&& temp)
{
cout << "move = B" << endl;
this->buf = temp.buf;
temp.buf = nullptr;
return std::move(*this);
}
};
int main()
{
list<B> list_;
for (auto a : { 1, 2, 4 })
{
cout << "-------begin------" << endl << endl;
list_.push_back(B());
}
cout << "-------1------" << endl;
list_.clear();
cout << "-------2------" << endl;
{
B a;
B b = a;
}
cout << "a = " << a << "cnt = " << cnt << endl;
getc(stdin);
return 1;
}
结果:
-------begin------
C
B
move B
-------begin------
C
B
move B
-------begin------
C
B
move B
-------1------
~B
~C
~B
~C
~B
~C
-------2------
C
B
C copy
copy B
~B
~C
~B
~C
a = 0cnt = 0
进程间通信
消息(Message)队列:消息队列是消息链式队列,消息被读完就删除,可以供多个进程间通信。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。
/**
* @file share-memory.h
* @brief 进程间通信-共享内存头文件封装
* 共享内存创建之后,一直存在于内核中,读完之后,内容还存在,直到被删除或系统关闭
* @author yanjingang
*/
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/shm.h>
#include <unistd.h>
#include <iostream>
#define PATHNAME "."
#define PROCID 'b' //0x6666
#define MEMSIZE 4096*1
using namespace std;
namespace mars {
namespace ipc {
// 共享内存类
class ShareMemory{
private:
// key
int key_;
// 共享内存ID
int shmid_;
// 共享内存大小
int size_;
// 创建共享内存
int create_share_memory();
public:
ShareMemory();
ShareMemory(const size_t m_size);
virtual ~ShareMemory();
// 变量返回
int key(){return key_;}
int shmid(){return shmid_;}
int size(){return size_;}
// 共享内存指针
char* mem;
};
// 构造函数
ShareMemory::ShareMemory(){
this->size_ = MEMSIZE;
int ret = this->create_share_memory();
if(ret != 0){
cout << "create_share_memory fail!" << endl;
}
}
// 构造函数
ShareMemory::ShareMemory(const size_t m_size){
this->size_ = m_size;
int ret = this->create_share_memory();
if(ret != 0){
cout << "create_share_memory fail!" << endl;
}
}
// 创建共享内存
int ShareMemory::create_share_memory(){
// 创建key, 以实现非亲缘关系进程间通信
key_ = ftok(PATHNAME, PROCID);
if (key_ == -1) {
cout << "create key file..." << endl;
FILE* fp;
if ((fp=fopen(PATHNAME,"a")) == nullptr){
cout << "keyfile created failed" << endl;
return -2;
}
fclose(fp);
key_ = ftok(PATHNAME, PROCID);
if (key_ == -1) {
cout << "key created failed" << endl;
return -1;
}
}
cout << "mq key:" << key_ << endl;
// 创建共享内存
shmid_ = shmget(key_, this->size(), IPC_CREAT | 0777); // 以ftok创建的key,需要IPC_CREAT参数
//shmid_ = shmget(IPC_PRIVATE, 128, 0777); // 在内核中生成共享内存的对象;相当于缓存,只能实现有亲缘关系进程间通信
if (shmid_ == -1) {
cout << "shmget create share memory fail!" << endl;
return -3;
}
cout << "shmget create share memory success! shmid:" << shmid() << " size:" << size() << endl;
// 返回这块内存的虚拟地址(将申请的共享内存挂接在该进程的页表上,是将虚拟内存和物理内存相对应)
mem = (char*)shmat(shmid_, NULL, 0);
if (mem == nullptr) {
cout << "shmat share memory mapping fail!" << endl;
return -4;
}
return 0;
}
// 析构函数
ShareMemory::~ShareMemory()
{
// 将用户空间的内存释放
shmdt(mem);
// 将内核空间的内存释放
shmctl(shmid_, IPC_RMID, NULL);
}
}
}
/**
* @file share-memory-set.cc
* @brief 进程间通信-共享内存set测试
* 共享内存创建之后,一直存在于内核中,读完之后,内容还存在,直到被删除或系统关闭
* @author yanjingang
* @note 编译:g++ mars/ipc/share-memory-set.cc -std=c++11 -Wall -o build/ipc-share-memory-set
*/
#include "share-memory.h"
using namespace std;
int main() {
mars::ipc::ShareMemory shm; //(4096);
while (true) {
// cout << "input content: ";
// fgets(shm.mem, shm.size(), stdin);
printf("input content: ");
fflush(stdout);
ssize_t n = read(0, shm.mem, 4096 - 1); //从标准输入获取消息
if (n > 0) {
shm.mem[n - 1] = '\0'; //过滤掉从标准输入中获取的换行
}
cout << "get share memory content: " << shm.mem << endl;
}
return 0;
}
/**
* @file share-memory-get.cc
* @brief 进程间通信-共享内存get测试
* 共享内存创建之后,一直存在于内核中,读完之后,内容还存在,直到被删除或系统关闭
* @author yanjingang
* @note 编译:g++ mars/ipc/share-memory-get.cc -std=c++11 -Wall -o build/ipc-share-memory-get
*/
#include "share-memory.h"
using namespace std;
int main() {
mars::ipc::ShareMemory shm; //(4096);
while (true) {
sleep(1);
cout << "get share memory content: " << strlen(shm.mem) << " - " << shm.mem << endl;
}
return 0;
}
// 执行结果
$ ./build/ipc-share-memory-set
mq key:1644681260
shmget create share memory success! shmid:589825 size:4096
input content: abc
get share memory content: abc
input content: 123
get share memory content: 123
input content: xyz
get share memory content: xyz
$ ./build/ipc-share-memory-get
mq key:1644681260
shmget create share memory success! shmid:589825 size:4096
get share memory content: 0 -
get share memory content: 3 - abc
get share memory content: 3 - 123
get share memory content: 3 - 123
get share memory content: 3 - xyz
get share memory content: 3 - xyz
// 查看共享内存
$ ipcs -m
IPC status from <running system> as of Mon Jan 4 19:29:31 CST 2021
T ID KEY MODE OWNER GROUP
Shared Memory:
m 327682 0x6607d82c --rw-rw-rw- yanjingang staff
// 关闭共享内存
$ ipcrm -m 327682
#include <iostream>
#include <thread>
#include <semaphore>
using namespace std;
counting_semaphore sema(1);
counting_semaphore semb(0);
counting_semaphore semc(0);
void pthread_fun1() //线程函数 1 打印 a
{
int i = 0;
for (; i < 10; ++i)
{
sema.acquire();
cout << "A" << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(200));
semb.release();
}
}
void pthread_fun2() //线程函数 2 打印 l
{
int i = 0;
for (; i < 10; ++i)
{
semb.acquire();
cout << "B" << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(200));
semc.release();
}
}
void pthread_fun3() //线程函数 3 打印 i
{
int i = 0;
for (; i < 10; ++i)
{
semc.acquire();
cout << "C" << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(200));
sema.release();
}
}
int main()
{
thread s1(pthread_fun1);
thread s2(pthread_fun2);
thread s3(pthread_fun3);
s1.join();
s2.join();
s3.join();
system("pause");
return 0;
}
继承多态
#include<iostream>
#include<string>
using namespace std;
string GetMyString()
{
return "This is a string";
}
class zheng
{
private:
int a;
public:
zheng() { a = 0;
cout << "initional construct" << endl; };
zheng(zheng& z){
cout << "Lvalue copy construct" << endl;
}
zheng(zheng && z){
cout << "Rvalue copy construct" << endl;
}
zheng(const int&& x):a(x){
cout << "value copy construct" << endl;
}
virtual ~zheng(){
cout << "destruct construct" << endl;
}
void set(int b)
{
a = b;
}
int get()
{
return a;
}
};
struct test1
{
private:
//zheng a;
public:
test1(){
cout << "test1 zheng costruct" << endl;
}
test1( zheng& s)
{
cout << "test1 L zheng construct" << endl;
}
test1( zheng&& s)
{
cout << "test1 R zheng construct" << endl;
}
~test1(){
cout << "test1 zheng destruct" << endl;
}
// int get()
// {
// return a.get();
// }
};
struct test:public test1, zheng
{
private:
//zheng a;
public:
test(){
cout << " zheng costruct" << endl;
}
test( zheng& s)
{
cout << "L zheng construct" << endl;
}
test( zheng&& s)
{
cout << "R zheng construct" << endl;
}
~test(){
cout << " zheng destruct" << endl;
}
// int get()
// {
// return a.get();
// }
};
int main(int argc, char const *argv[])
{
test *p = new test;
zheng *p1 = p;
delete p1;
cout << "123" << endl;
return 0;
}
socket连接
server
int port = 6000;
string host = "127.0.0.1";
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
Socket sSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sSocket.Bind(ipe);
sSocket.Listen(0);
Console.WriteLine("监听已经打开,请等待");
//receive message
Socket serverSocket = sSocket.Accept();
Console.WriteLine("连接已经建立");
string recStr = "";
byte[] recByte = new byte[4096];
int bytes = serverSocket.Receive(recByte, recByte.Length, 0);
recStr += Encoding.ASCII.GetString(recByte, 0, bytes);
//send message
Console.WriteLine("服务器端获得信息:{0}", recStr);
string sendStr = "send to client :hello";
byte[] sendByte = Encoding.ASCII.GetBytes(sendStr);
serverSocket.Send(sendByte, sendByte.Length, 0);
serverSocket.Close();
sSocket.Close();
client
int port = 6000;
string host = "127.0.0.1";//服务器端ip地址
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(ipe);
//send message
string sendStr = "send to server : hello,ni hao";
byte[] sendBytes = Encoding.ASCII.GetBytes(sendStr);
clientSocket.Send(sendBytes);
//receive message
string recStr = "";
byte[] recBytes = new byte[4096];
int bytes = clientSocket.Receive(recBytes, recBytes.Length, 0);
recStr += Encoding.ASCII.GetString(recBytes, 0, bytes);
Console.WriteLine(recStr);
clientSocket.Close();
生产者消费者模型
#include <iostream>
#include <thread>
#include <deque>
static std::mutex mtx;
static std::deque<int> dq;
static int productNum = 5;
void Producer()
{
using namespace std::literals::chrono_literals;
for (int i = 1; i <= productNum; ++i) {
mtx.lock();
dq.push_front(i);
std::cout << "Producer 生产产品为: " << i << std::endl;
mtx.unlock();
// std::this_thread::sleep_for(1s);
}
}
void Consumer()
{
while (true) {
if (dq.empty()) {
continue;
}
mtx.lock();
int data = dq.back();
dq.pop_back();
std::cout << "Consumer 消费产品为: " << data << std::endl;
mtx.unlock();
}
}
int main()
{
std::thread t1(Producer);
std::thread t2(Consumer);
t2.join();
t1.join();
std::cin.get();
}
单例模式
//利用智能指针解决释放问题
class SingleAuto
{
private:
SingleAuto()
{
}
SingleAuto(const SingleAuto &) = delete;
SingleAuto &operator=(const SingleAuto &) = delete;
public:
~SingleAuto()
{
cout << "single auto delete success " << endl;
}
static std::shared_ptr<SingleAuto> GetInst()
{
if (single != nullptr)
{
return single;
}
s_mutex.lock();
if (single != nullptr)
{
s_mutex.unlock();
return single;
}
single = std::shared_ptr<SingleAuto>(new SingleAuto);
s_mutex.unlock();
return single;
}
private:
static std::shared_ptr<SingleAuto> single;
static mutex s_mutex;
};
// 智能指针方式
std::shared_ptr<SingleAuto> SingleAuto::single = nullptr;
mutex SingleAuto::s_mutex;
void test_singleauto()
{
auto sp1 = SingleAuto::GetInst();
auto sp2 = SingleAuto::GetInst();
cout << "sp1 is " << sp1 << endl;
cout << "sp2 is " << sp2 << endl;
//此时存在隐患,可以手动删除裸指针,造成崩溃
// delete sp1.get();
}
int main(){
test_singleauto();
}
工厂模式
#include <iostream>
#include <vector>
using namespace std;
typedef enum ProductTypeTag
{
Hair,
Hisense,
}PRODUCTTYPE;
//抽象产品类 TV(电视机类)
class TV
{
public:
virtual void Show() = 0;
virtual ~TV(){};//声明析构函数为虚函数,防止内存泄漏
};
//具体产品类 HairTV(海尔电视类)
class HairTV : public TV
{
public:
void Show()
{
cout<<"I'm HairTV "<<endl;
}
};
//具体产品类 HisenseTV(海信电视类)
class HisenseTV : public TV
{
public:
void Show()
{
cout<<"I'm HisenseTV"<<endl;
}
};
// 工厂类 TVFactory(电视机工厂类)
class TVFactory
{
public:
TV* CreateTV(PRODUCTTYPE type)
{
switch (type)
{
case Hair:
return new HairTV();
case Hisense:
return new HisenseTV();
default:
return NULL;
}
}
};
int main(int argc, char *argv[])
{
// 创建工厂类对象
TVFactory* myTVFactory = new TVFactory();
TV* hairTV = myTVFactory->CreateTV(Hair);
if (hairTV != NULL)
hairTV->Show();
TV* hisenseTV = myTVFactory->CreateTV(Hisense);
if (hisenseTV != NULL)
hisenseTV->Show();
delete myTVFactory;
myTVFactory = NULL;
delete hairTV;
hairTV = NULL;
delete hisenseTV;
hisenseTV = NULL;
return 0;
}
————————————————
版权声明:本文为CSDN博主「herryone123」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kenjianqi1647/article/details/119632618
手撕排序
插入排序
void insertion_sort(int arr[], int length)
{
int i, j;
for (i = 1; i < length; i++)
{
int tmp = arr[i];
for (j = i; j>0 && arr[j-1]>tmp; j--)
{
arr[j] = arr[j-1];
}
arr[j] = tmp;
}
}
冒泡排序
void bubbleSort(vector<int>& a)
{
bool swapp = true;
while (swapp)
{
// for循环如果不执行,排序已完成
swapp = false;
for (int i = 0; i < a.size()-1; i++)
{
// 每次扫描只交换相邻数据
if (a[i] > a[i+1])
{
int tmp = a[i+1];
a[i+1] = a[i];
a[i] = tmp;
swapp = true;
}
}
}
}
归并排序
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
int L[n1], R[n2];
// 暂存数组值
for(i = 0; i < n1; i++)
{
L[i] = arr[l+i];
}
for(j = 0; j < n2; j++)
{
R[j] = arr[m+1+j];
}
i = 0;
j = 0;
k = l;
// 双指针法排序
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
// 补全剩余长度
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
}
void mergeSort(int arr[], int l, int r)
{
if (l < r)
{
// 中间数归到左边
int m = l + (r - l)/2;
mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, r);
}
}
堆排序
// first method
void heapify(int arr[], int start, int end)
{
int dad = start;
int son = 2*dad+1;
while (son <= end)
{
// 右根节点更大
if (son+1 <= end && arr[son] < arr[son+1])
{
son++;
}
// 从后往前的初始化方式保证正确性
if (arr[dad] > arr[son])
{
return;
}
else
{
swap(arr[dad], arr[son]);
dad = son;
son = dad*2 + 1;
}
}
}
void heap_sort(int arr[], int len)
{
for(int i = len/2-1; i>=0; --i)
{
heapify(arr, i, len-1);
}
for (int i = len-1; i>0; i--)
{
// 将最大值放在尾部,交换到头部的大值会被heapify一直弹下去
swap(arr[0], arr[i]);
// 不对第i项进行排序
heapify(arr, 0, i-1);
}
}
// second method
void heapify(int arr[], int n, int i)
{
int largest = i;
int l = 2*i + 1;
int r = 2*i + 2;
if (l < n && arr[l] > arr[largest])
largest = l;
if (r < n && arr[r] > arr[largest])
largest = r;
if (largest != i)
{
int tmp = arr[largest];
arr[largest] = a[i];
arr[i] = tmp;
heapify(arr, n, largest);
}
}
void heapSort(int arr[], int n)
{
// 从堆底前的一个元素开始从后往前建立最大堆
for (int i = n / 2 - 1; i>=0; i--)
{
heapify(arr, n, i);
}
// 从堆顶开始往后面扔 + 每次重新建立最大堆
for (int i=n-1; i>=0; i--)
{
swap(arr[0], arr[i]);
heapify(arr, i, 0);
}
}
快速排序
void QuickSort(int* array, int low, int high)
{
if(low >= high)
{
return;
}
int i = low;
int j = high;
int partition = arraw[low];
// 双指针相遇时,i所在的位置就是基数插入位置
while (i<j)
{
// 先从high位开始,因为基数选择了low
while(array[j] >= partition && i < j)
{
j--;
}
array[i] = array[j];
// i和j位置的数字交替被拷贝走,所以不需要交换
while(array[i] <= partition && i < j)
{
i++;
}
array[j] = array[i];
}
array[i] = key;
// 分治
QuickSort(array, low, i - 1);
QuickSort(array, i+1, high);
}