# CPP 学习笔记
可以直接下载pdf CPP 学习笔记
<li>QT Creator 编译带<thread>的CPP有BUG,暂时不知道怎么去除!
<a id="markdown-0112-代码1" name="0112-代码1"></a>
#### 0.1.1.2. 代码1
```#include <iostream>
#include <stdlib.h>v
#include <thread>
using namespace std;
void run(char* p)
{
int i=0;
i=system(p);
}
int main()
{
char p[5][20]={
"ls",
"echo nihao",
"gnome-terminal",
"terminator",
"ps -aux"
};
while("nimei")
{
static int i(0);
if(i<5){
thread *pt=new thread(run,p[i]);
i+=1;
cout<<"I now is :\t"<<i<<endl;
}
else{
break;
}
cout<<"Breaking...."<<endl;
}
cin.get();
return 0;
}
关键字 | 详细解释 |
---|---|
id | Thread的id |
native_handle_type | native_handle_type |
operator= | Move massive Thread |
get_id | get Thread ID |
joinable | get if joinable |
join | join thread |
detach | detach thread |
swap | swap thread |
native_handle | get native handle |
hardware_concurrency[static] | Detect hardware concurrency (public static function) |
#include <iostream>
#include <stdlib.h>
#include <thread>
#include <atomic>
using namespace std;
int count(0);
void run()
{
for(int i(0);i<1000000;i++)
{
count++;
cout<<"\t"<<i<<"\t"<<count<<"\t";
}
}
int main()
{
auto n=thread::hardware_concurrency();
thread* pt[n];
for(int z=0;z<n;z++)
{
pt[z]=new thread(run);
pt[z]->detach();
}
cout<<"Finally count is \t"<<count<<endl;
cout<<"Used "<<n <<"threads"<<endl;
cin.get();
return 0;
}
运行结果不是1000000×2.
#include <stdlib.h>
#include <thread>
#include <atomic>
using namespace std;
int count(0);
void run()
{
for(int i(0);i<1000000;i++)
{
count++;
cout<<"\t"<<i<<"\t"<<count<<"\t";
}
}
int main()
{
auto n=thread::hardware_concurrency();
thread* pt[n];
for(int z=0;z<n;z++)
{
pt[z]=new thread(run);
pt[z]->detach();
}
cout<<"Finally count is \t"<<count<<endl;
cout<<"Used "<<n <<"threads"<<endl;
cin.get();
return 0;
}
运行结果是1000000×2.正确
atomic 声明方式为 atomic<int> a(100); 等号初始化会报错 vim 按CTRL+S 后假死按 CTRL+q 退出#include <iostream>
#include <vector> //容器
#include <algorithm> //算法
using namespace std;
//专么实现一个类模板,实现打印
//类模板实现了方法
template <class T>
class vector_s {
public:
void operator()(const T &t1) //重载了小括号 实现访问小括号就直接打印
{
cout << t1 << endl;
}
};
int main(void)
{
vector<int> myv;
myv.push_back(13);
myv.push_back(23);
myv.push_back(33);
myv.push_back(113);
myv.push_back(1995);
myv.push_back(1996);
vector_s<int> print; // 对打印实现实例化
//myv.begin(), myv.end() 是迭代器 本质是指针
// for_each 本质是一个算法
for_each(myv.begin(), myv.end(), print);
cin.get();
return 0;
}
-有些算法并不依赖于数据结构的特定实现,而只依赖于该结构的几个基本语义属性
-STL 抽象出的这些基本属性(concept)成功的将算法和数据结构相分离,在没有效率损失的前提下,获得了极大的弹性!
-容器 (container)
-算法Algorithm
-迭代器 (iterator)
-仿函数 (Function Object)
-适配器 (Adaptor)
-空间制配器 (allocator)
获取远程代码修改后,想要push到远端与原来不同的新分支,可以使用下面的命令实现: git push origin 本地分支:远端希望创建的分支
例如git下来的分支为master
git branch master
git push origin master:my_remote_new_branch
#远端即可创建新的分支my_remote_new_branch,提交本地修改
std::for_each(arr.begin(), arr.end(), func);
比较有用的for_each 用法
for (auto n:Original)
C++ 11 新的for
class MyClass
typename T::SubType * ptr; //typename 直接指示 T::SubType * 为一个类型 没有typename 会被解析为
// T域中的 SubType 静态成员 乘于(*) ptr.
...
};
-typename 的第二个作用:在模板声明中替换class -
template <typename T > class Myclass;
-用于管理一组元素
-每个元素都有固定位置--去结余插入时机和地点,和元素值无关 -vector list deque
-元素取决于特定的排序准则,和插入顺序无关
-set multiset map multimap
array <int ,5>={1,2,3,4,5};
-静态数组,栈上
mv.push_back()
-不需要变长,容量较小,array 需要变长,容量较大,用vector
-list容器是无序容器
-list 容器只能通过迭代器访问。通过++ -- 遍历
-list容器可以使用remove()方法删除元素,
-可以同时正向和反向查找
-可以使用sort()函数排序
-可以使用merge 合并,但是合并之前必须排序
-可以使用unique()函数删除重复项,删除前必须排序。
--merge (使)合并,结合,并入;相融;融入;渐渐消失在某物中
-set容器不能有重复项,重复的会被舍弃 -set容器会自动排序 -set 用insert插入元素 -set可以用find()函数查找位置
循环加栈
find()函数可以查找数组、容器中的元素。
for_each(); 遍历每一个元素。
multiset和set差不多,但是允许重复元素。
迭代器本质是智能指针。
auto ifind=find_if(mylist.bengin(),mylisy.end(),bindlst(greater<int>(),3));
bindlst 需要头文件 funtional #include <functional>
bindlst(greater<int>(),3);
绑定一个函数。 greater<int>()
是一个仿函数(functional) 是一个重载了()的类/结构 体 ,可以用来实现一定的算法策略。
仿函数例子:
#include <list>
#include <functional>
#include <array>
#include <algorithm>
using namespace std;
class shuchu {
public:
void operator()(int x)
{
std::cout<<x<<endl;
}
};
int main(int argc, char const *argv[]) {
/* code */
// array<int,5>array1({1,2,3,4,5});
list <int>ls1;
ls1.push_back(1);
ls1.push_back(3);
ls1.push_back(5);
ls1.push_back(7);
ls1.push_back(9);
auto ib=ls1.begin();
auto ie=ls1.end();
for_each(ib,ie,shuchu());
cin.get();
return 0;
}
2019.11.15
-智能指针有一个_Ptr属性,可以打印里面的指针。
-STL 有bug 先访问迭代器的_Ptr属性,再访问迭代器指针正常,但是反过来会出错。
-分行打印就没有问题。
2019.11.15
-用法
stack <mystack>; //声明一个栈
mystack.push(num); //压栈
mystack.pop(); //出栈
mystack.top(); //获取第一个元素
stack成员函数示例 -size( ) :返回栈中元素个数 -top( ) :返回栈顶的元素 -pop( ) :从栈中取出并删除元素 -push(e) :向栈中添加元素e -empty( ) :栈为空时返回true
-queue 英 [kju?] 美 [kju?]
n.(人、汽车等的)队,行列;(储存的数据)队列 v.(人、车等)排队等候;(使)排队;列队等待
-queue 需要头文件 <queue>
-从网上拔来的Queue
(1) 构造函数
deque():创建一个空deque
deque(int nSize):创建一个deque,元素个数为nSize
deque(int nSize,const T& t):创建一个deque,元素个数为nSize,且值均为t
deque(const deque &):复制构造函数
(2) 增加函数
void push_front(const T& x):双端队列头部增加一个元素X
void push_back(const T& x):双端队列尾部增加一个元素x
iterator insert(iterator it,const T& x):双端队列中某一元素前增加一个元素x
void insert(iterator it,int n,const T& x):双端队列中某一元素前增加n个相同的元素x
void insert(iterator it,const_iterator first,const_iteratorlast):双端队列中某一元素前插入另一个相同类型向量的[forst,last)间的数据
(3) 删除函数
Iterator erase(iterator it):删除双端队列中的某一个元素
Iterator erase(iterator first,iterator last):删除双端队列中[first,last)中的元素
void pop_front():删除双端队列中最前一个元素
void pop_back():删除双端队列中最后一个元素
void clear():清空双端队列中最后一个元素
(4) 遍历函数
reference at(int pos):返回pos位置元素的引用
reference front():返回手元素的引用
reference back():返回尾元素的引用
iterator begin():返回向量头指针,指向第一个元素
iterator end():返回指向向量中最后一个元素下一个元素的指针(不包含在向量中)
reverse_iterator rbegin():反向迭代器,指向最后一个元素
reverse_iterator rend():反向迭代器,指向第一个元素的前一个元素
(5) 判断函数
bool empty() const:向量是否为空,若true,则向量中无元素
(6) 大小函数
Int size() const:返回向量中元素的个数
int max_size() const:返回最大可允许的双端对了元素数量值
(7) 其他函数
void swap(deque&):交换两个同类型向量的数据
void assign(int n,const T& x):向量中第n个元素的值设置为x deque网上扒来的
#include <set>
#include <string>
#include <stdio.h>
#include <string.h>
using namespace std;
class strless
{
public:
bool operator () (const char* p,const char* p1)
{
return strcmp(p, p1) < 0;
}
private:
};
int main(void)
{
const char* cmd[] = { "nihao","spectrc","calc","good" };
set<const char *, strless>myset(cmd,cmd+4,strless());
auto ib = myset.begin();
auto ie = myset.end();
for (auto i : myset)
{
cout << i << endl;
}
return 0;
}
#include <set>
#include <string.h>
using namespace std;
class stu{
public:
int id;
char p[100];
};
class stuless
{
public:
bool operator ()(const stu &st1,const stu &st2)
{
return st1.id<st2.id;
}
};
int main()
{
stu student[3]={
{99,"zhuang"},
{15,"li"},
{3,"ooooo"}
};
stu newstu;
newstu.id=100782;
strcpy(newstu.p,"nimeide");
multiset<stu,stuless> stu1 (student,student+3,stuless());
stu1.insert(newstu);
strcpy(newstu.p,"SBSBSBSB");
stu1.insert(newstu);
strcpy(newstu.p,"luo liuo");
stu1.insert(newstu);
for(auto i:stu1)
{
cout<< "\t"<<i.id<<"\t"<<i.p<<endl;
}
return 0;
}
输出
#include <string>
#include <map>
#include <stdlib.h>
using namespace std;
class worker{
public:
int id;
string name;
string work;
};
class winfo{
public:
int randid;
worker w1;
};
int main()
{
system("chcp 65001");
winfo warr[]={
{1,{10,"李四","mugong"}},
{2,{9,"张三","mugong"}},
{8,{5,"wangermazi","mugong"}},
{20,{3,"gg","mugong"}},
{30,{1,"ww张三","mugong"}}
};
map <int,worker> m;
for(auto i : warr)
{
static int n=0;
m[warr[n].randid]=warr[n].w1;
n++;
}
auto ib=m.begin();
auto ie=m.end();
for(;ib!=ie;ib++)
{
cout<<"\t winfo.randid is \t"<<(*ib).first<<" worker info is \t"<<(*ib).second.id<<"\t"<<(*ib).second.name
<<"\t"<<(*ib).second.work<<"\t"<<endl;
}
return 0;
}
输出
m.insert(pair<const char*,int> ("第一个"),1);
m.insert(pair<const char*,int> ("第二个"),2);
m.insert(pair<const char*,int> ("第三个"),5);
m.insert(pair<const char*,int> ("第四个"),8);
char str[54];
str="123456";
erase() 函数可删除字符串。 str1.erase(3,4); erase(str1.begin(),str.begin()+2);
replace() 替换函数 str1.replace(3,3,"China");str1.replace(3,"China"); str1.replace(3,"China"); replace (位置,长度,字符串);
str.find() 查找字符串,找到第一个匹配的字符的位置,找不到返回-1;
rfind() 反向查找,返回找的的第一个的匹配的字符串的位置。找不到返回-1;
find_first_of () 找到第一个并返回所在位置。
find_first_not_of () 找到第一个不匹配的并返回所在位置。
find_last_of () 找到最后一个匹配的并返回所在位置。
find_last_not_of () 找到最后一个不匹配的并返回所在位置。
auto func=[](int a ,int b){ return a+b;};
for_each(myvector.begin(),myvector.end(),[](int a){return a*=2;cout<<a<<endl;});
严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C3861 “_Access”: 找不到标识符 GPU_hello c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.15.26726\include\amp.h 2616
严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C3588 在 amp 限制代码中不支持从“unknown-type”转换为“void *” GPU_hello c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.15.26726\include\amp.h 2616
#include <amp.h>
#include <iostream>
using namespace std;
using namespace concurrency;
int main(void)
{
int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
array_view<int> av(10, a); //GPU 计算结构 AV 存储到GPU的显存
/*
*[=](index<1>idx) restrict (amp) {av[idx] *= 2; }
* [=] 标识直接操作这个数据
* restrict (amp) 标识定位到 GPU进行运算
*这个表达式为Lambda表达式
*/
parallel_for_each(av.extent, [=](index<1> idx) restrict (amp) {av[idx] *= 2; });
for (int i = 0; i < 10; i++)
{
cout << "\t" << av[i] << endl;
}
cin.get();
}
在一个类内部记录另一个类的快照状态的模式。可以再合适的时候跳回复用
设计备忘录的三大步骤:
策略模式针对一组算法,将每一个算法封装到具有共同接口的独立类中。
从而使得他们可以相互转换,策略模式可以在不影响客户端的情况下使算法发生改变。策略模式把行为和环境分离开来,环境类负责维持和查询行为类。
策略模式依赖多态,策略模式的抽象类,接口,抽象类的指针可以访问所有子类对象(纯虚函数)
各种策略的实现类。都必须集成抽象类。
=======
代码: simple_factory
代码: factory_method
不能在linux 下编译!!! 报错 only nonstatic member functions may be virtual
class {
public:
int a=100;
}aa;
把执行命令单独建一个类。专职做命令的执行工作
命令的执行者专么建一个基类,存放执行不同命令的类继承自这个基类。通过执行不同命令划分。
再建一个类统筹这些执行命令的类,调用执行命令的类。
代码: 命令模式示例代码
20140903
using namespace std;
class A
{
public:
void virtual a() {
std::cout << "A --> a" << endl;
}
void virtual b() {
std::cout << "A--> b" << endl;
}
void virtual c() {
std::cout << "A--> c" << endl;
}
private:
};
class B :public A
{
public:
void virtual a()
{
std::cout << "B--> a" << endl;
}
void virtual b() {
std::cout << "B--> b" << endl;
}
};
typedef void (*Pfunc) (void);
int main(void)
{
B b;
cout << "B is " <<sizeof(b) << endl;
Pfunc pfc;
for (int i = 0; i < 3; i++)
{
/* (&b) 取出B的地址
(int *)(&b) 转换b的地址为int 类型,方便后期访问紧跟着它的内存
*(int *)(&b) 取出B里面的内容(虚函数表的地址)
(int *) *(int *)(&b) 把虚函数表的地址转换为int类型,方便后期访问紧跟着它的内存
(int *) *(int *)(&b) + i 利用地址存储的机制,+1 自动跳过4(8)个字节,访问下一个内存内容,访问存储在虚函数表里面的函数地址
(Pfunc)* 将虚函数表李的函数指针地址转换为 pFunc 类型的函数指针地址,方便调用
pfc(); 调用
*/
pfc = (Pfunc)*((int *) *(int *)(&b) + i);
pfc();
}
cin.get();
return 0;
}
#define DVECTOR_H
#pragma once
#include <iostream>
template <class T>
class dvector
{
public:
dvector();
~dvector();
bool push_back(T);
void show();
public:
T* p;
int len;
int real_len;
};
#endif // DVECTOR_H
template <class T>
dvector<T>::dvector()
{
len=real_len =0;
p=nullptr;
}
template<class T>
dvector<T>::~dvector()
{
if(p!=nullptr)
{
delete []p;
p=nullptr;
}
}
template <class T>
void dvector<T>::show()
{
if(p!=nullptr)
{
for(int i=0;i<real_len;i++){
std::cout<<i<<"\t"<<*(p+i)<<std::endl;
}
std::cout<<"length="<<real_len<<std::endl;
}else {
std::cout<<"NNNNNNNNNNNNNNNNNNNNNNNNNNo thing"<<std::endl;
}
}
template<class T>
bool dvector<T>::push_back(T t){
if(p==nullptr)
{
//第一个为空说明只有一个元素
p=new T;
*p=t;
real_len=len=1;
}else {
//第一个不为空说明有多个元素,这时候链表就必须重新分配内存
//分配为数组形式
T *ptemp = new T[real_len+1];
for(int i=0;i<real_len;i++)
{
*(ptemp+i)=*(p+i);
}
*(ptemp+real_len)=t;
delete []p;
p=ptemp;
real_len+=1;
len+=1;
}
return true;
}
int main()
{
//测试基本类型
//string 会出错,因为string 不是基本类型,是一种类似 vector 的类模板,其内部的内存操作与基本类型不一样。
//1. int
dvector<int>* dv1=new dvector<int>;
dv1->push_back(12);
dv1->push_back(15);
dv1->push_back(1995);
dv1->push_back(200);
dv1->push_back(2);
dv1->push_back(1);
dv1->show();
//2. double
dvector<double>* dv2=new dvector<double>;
dv2->push_back(12.2);
dv2->push_back(15.3);
dv2->push_back(1995.0220);
dv2->push_back(200.1);
dv2->push_back(2.3);
dv2->push_back(1.9);
dv2->show();
//3. char*
dvector<char*>* dv3=new dvector<char*>;
dv3->push_back("nimei");
dv3->push_back("de");
dv3->push_back("垃圾");
dv3->push_back("95");
dv3->push_back("lalala");
dv3->push_back("45");
dv3->show();
return 0;
}
和尹成老师视频里面写的不一样。。自己写的。反正就是不规范就是了
#define DVECTOR_H
#pragma once
#include <iostream>
template <class T>
class dvector
{
public:
dvector();
~dvector();
bool push_back(T);
bool del(T);
bool modify(T, T);
int search(T t);
void show();
public:
T* p;
int len;
int real_len;
};
#endif // DVECTOR_H
using namespace std;
template <class T>
dvector<T>::dvector()
{
len=real_len =0;
p=nullptr;
}
template<class T>
dvector<T>::~dvector()
{
if(p!=nullptr)
{
delete []p;
p=nullptr;
}
}
//遍历输出
template <class T>
void dvector<T>::show()
{
if(p!=nullptr)
{
for(int i=0;i<real_len;i++){
std::cout<<i<<"\t"<<*(p+i)<<std::endl;
}
std::cout<<"length="<<real_len<<std::endl;
}else {
std::cout<<"NNNNNNNNNNNNNNNNNNNNNNNNNNo thing"<<std::endl;
}
}
//增
template<class T>
bool dvector<T>::push_back(T t){
if(p==nullptr)
{
//第一个为空说明只有一个元素
p=new T;
*p=t;
real_len=len=1;
}else {
//第一个不为空说明有多个元素,这时候链表就必须重新分配内存
//分配为数组形式
T *ptemp = new T[real_len+1];
for(int i=0;i<real_len;i++)
{
*(ptemp+i)=*(p+i);
}
*(ptemp+real_len)=t;
delete []p;
p=ptemp;
real_len+=1;
len+=1;
}
return true;
}
//查 返回查找到的序号
template <class T>
int dvector<T>::search(T t)
{
if (p ==nullptr)
{
std::cout << "The dvector is empty ,abort!" << std::endl;
return false;
}
else
{
for (size_t i = 0; i < real_len; i++)
{
if (*(p+i) == t)
{
cout << "FIND " << t << "at the position of " << i<<" " << endl;
return i;
}
}
cout << "no such a thing" << endl;
return -1;
}
return -1;
}
//删
template <class T>
bool dvector<T>::del(T t)
{
if (p == nullptr)
{
std::cout << "The dvector is alreafy empty ,abort!" << std::endl;
return false;
}
else
{
for (size_t i = 0; i < real_len; i++)
{
if (*(p + i) == t)
{
cout << "Deleting" << endl;
cout << "FIND " << t << "at the position of " << i << " " << endl;
//如果是在第一个的情况
if (i == 0)
{
for (size_t i = 0; i < real_len; i++)
{
if (real_len == 1) //如果是只剩一个而且刚好第一个是要删除的
{
delete p;
p == nullptr;
real_len -= 1;
return true;
}
else
{ //还有多个且第一个是要删除的
T* tmp = new T[real_len - 1];
for (size_t k = 0; k < real_len-1; k++)
{
*(tmp + k) = *(p + k + 1);
}
delete[]p;
p = tmp;
real_len -= 1;
return true;
}
}
}
else if (i== real_len-1) //最后一个匹配要删除的时候
{
p + i == nullptr;
real_len -= 1;
}
else //在中间的情况
{
T* tmp = new T[real_len - 1];
for (size_t k = 0; k < i ; k++)
{
*(tmp + k) = *(p + k);
}
// 利用两个循环刚好跳过下标为i 的值 k 为原来的p 中的值,tmp+k-i 为新数组中的下标
for (size_t k = i+1; k < real_len; k++)
{
*(tmp + k - 1) = *(p + k);
}
delete[]p;
p = tmp;
real_len -= 1;
return true;
}
}
}
cout << "no such a thing,Delete failed!" << endl;
return false;
}
}
//改
template <class T>
bool dvector<T>::modify(T origin, T mo)
{
if (p == nullptr)
{
std::cout << "The dvector is empty ,abort!" << std::endl;
return false;
}
else
{
for (size_t i = 0; i < real_len; i++)
{
if (*(p + i) == origin)
{
cout << "Modifying" << endl;
cout << "FIND " << origin << "at the position of " << i << " " << endl;
*(p + i) = mo;
}
}
cout << "no such a thing ,Modify failed!" << endl;
return false;
}
return -1;
}
int main()
{
//测试基本类型
//string 会出错,因为string 不是基本类型,是一种类似 vector 的类模板,其内部的内存操作与基本类型不一样。
//1. int
dvector<int>* dv1=new dvector<int>;
dv1->push_back(12);
dv1->push_back(15);
dv1->push_back(1995);
dv1->push_back(200);
dv1->push_back(2);
dv1->push_back(1);
dv1->show();
//dv1->search(200);
//dv1->search(1000);
dv1->del(12);
dv1->show();
dv1->del(1995);
dv1->show();
dv1->del(1);
dv1->show();
dv1->modify(15, 33);
dv1->modify(200, 1);
dv1->modify(100, 1);
dv1->show();
// cout<<"next............"<<endl<<endl;
// //2. double
// dvector<double>* dv2=new dvector<double>;
// dv2->push_back(12.2);
// dv2->push_back(15.3);
// dv2->push_back(1995.0220);
// dv2->push_back(200.1);
// dv2->push_back(2.3);
// dv2->push_back(1.9);
//
// dv2->show();
//
// dv2->search(1.9);
//
// cout << "next............" << endl << endl;
//
// //3. char*
// dvector<const char*>* dv3=new dvector<const char*>;
// dv3->push_back("nimei");
// dv3->push_back("de");
// dv3->push_back("垃圾");
// dv3->push_back("95");
// dv3->push_back("lalala");
// dv3->push_back("45");
//
//dv3->show();
//dv3->search("nimei");
//cout << "next............" << endl << endl;
std::cin.get();
return 0;
}
书籍:Beyond the C++ Standard Library : An Introduction to Boost > > 注记(笔记)
虽然 C++ 标准库中提供了 std::auto_ptr, 但是它不能 完全满足我们对智能指针的需求。例如,auto_ptr 不能用作 STL 容器的元素。Boost 的智能指针类填充了标准所留下来的缺口。
它不能转让所有权,scoped_ptr 永远不能被复制或被赋值,scoped_ptr 拥有它所指向的资源的所有权,并永远不会放弃这个所有权
成员函数:
#include <iostream>
#include "boost/scoped_ptr.hpp"
#include <string>
using namespace std;
using namespace boost;
using namespace std;
int main(int argc, char ** argv)
{
scoped_ptr<string> st(new string("Scoped ptr Inner Text"));
//错误的做法,scoped_ptr 不能复制
//st = new scoped_ptr<string>;
cout << *st <<endl<<"Is "<<st->size()<<" length"<<endl;
*st = "文本已经改变!"; //但是scoped指针指向的内容是可以改变的,scoped_ptr 使用与普通指针没有区别!
cout << endl << *st;
cin.get();
// 此处 st 指针自动删除!不需要delete
return 0;
}
scoped_ptr 可以被 reset, 在需要时可以删除并替换被指物。
而对于 const auto_ptr 这是不可能的
定义
template<typename T> class shared_ptr {
public:
template <class Y> explicit shared_ptr(Y* p);
template <class Y,class D> shared_ptr(Y* p, D d);
shared_ptr(const shared_ptr & r);
template <class Y> explicit
shared_ptr(const weak_ptr<Y>& r);
template <class Y> explicit shared_ptr(std::auto_ptr<Y>& r);
shared_ptr& operator=(const shared_ptr& r);
void reset();
T& operator*() const;
T* operator->() const;
T* get() const;
bool unique() const;
long use_count() const;
operator unspecified_bool_type() const; //译注:原文是unspecified-bool-type(),有误
void swap(shared_ptr<T>& b);
};
template <class T,class U>
shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r);
}
template <class Y> explicit shared_ptr(Y* p);
template <class Y, class D> shared_ptr(Y* p, D d);
shared_ptr(const shared_ptr& r);
template <class Y> explicit shared_ptr(const weak_ptr<Y>& r);
template <typename Y> shared_ptr(std::auto_ptr<Y>& r);
~shared_ptr();
shared_ptr& operator=(const shared_ptr& r);
void reset();
T& operator*() const;
T* operator->() const;
T* get() const;
bool unique() const;
long use_count() const;
operator unspecified_bool_type() const;
void swap(shared_ptr<T>& b);
template <typename T,typename U> shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r);
有时你会发现你要把 shared_ptr 用于某个特别的类型,它需要其它清除操作而不是简单的 delete. shared_ptr 可以通过客户化删除器来支持这种需要。那些处理象 FILE* 这样的操作系统句柄的资源通常要使用 象 fclose 这样的操作来释放。要在 shared_ptr 里使用 FILE* ,我们要定义一个类来负责释放相应的资源。
注意
ared_array 用于共享数组所有权的智能指针。它与 shared_ptr 的关系就如 scoped_array 与 scoped_ptr 的关系。 shared_array 与 shared_ptr 的不同之处主要在于它是用于数组的而不是用于单个对象 的。在我们讨论 scoped_array时,我提到过通常 std::vector 是一个更好的选择。但 shared_array 比 vector 更有价值,因为它提供了对数组所有权的共享。 shared_array 的接口与 shared_ptr 非常相似,差别 仅在于增加了一个下标操作符,以及不支持定制删除器。
- intrusive_ptr 是 shared_ptr 的插入式版本。有时我们必须使用插入式的引用计数智能指针。典型的情况是对 于那些已经写好了内部引用计数器的代码,而我们又没有时间去重写它(或者已经不能获得那些代码了)。另一种情 况是要求智能指针的大小必须与裸指针大小严格相等,或者 shared_ptr 的引用计数器分配严重影响了程序的性 能(我可以肯定这是非常罕见的情况! )。从功能的观点来看,唯一需要插入式智能指针的情况是,被指类的某个成 员函数需要返回 this ,以便它可以用于另一个智能指针(事实上,也有办法使用非插入式智能指针来解决这个问 题,正如我们在本章前面看到的)。 intrusive_ptr 不同于其它智能指针,因为它要求你来提供它所要的引用计 数器。 当 intrusive_ptr 递增或递减一个非空指针上的引用计数时,它是通过分别调用函数 intrusive_ptr_add_ref 和 intrusive_ptr_release 来完成的。这两个函数负责确保引用计数的正确性,并且负责在引用计数降为零时 删除指针。因此,你必须为你的类重载这两个函数,正如我们后面将看到的。
template<class T> class intrusive_ptr {
public:
intrusive_ptr(T* p,bool add_ref=true);
intrusive_ptr(const intrusive_ptr& r);
~intrusive_ptr();
T& operator*() const;
T* operator->() const;
T* get() const;
operator unspecified-bool-type() const;
};
template <class T> T* get_pointer(const intrusive_ptr<T>& p);
template <class T,class U> intrusive_ptr<T>
static_pointer_cast(const intrusive_ptr<U>& r);
}
#include <iostream>
#include "boost/scoped_ptr.hpp"
#include <string>
#include "boost/algorithm/string.hpp" //String_algo 算法
#include "boost/shared_ptr.hpp"
//#include "boost/container/vector.hpp"
#include <vector>
#include <fstream>
#define SCOPED_PTR 0
#define SHARED_SIMPLE 0
#define SHARED_FILE 1
using namespace boost;
using std::cin;
using std::cout;
using std::endl;
class filecloser
{
public:
filecloser();
~filecloser();
void operator()(std::fstream *fs)
{
cout << "Now starting to close the file resourse" << endl;
if (fs)
{
fs->close();
cout << "File Closed" << endl;
}
}
private:
};
filecloser::filecloser()
{
}
filecloser::~filecloser()
{
}
//#define shared_ptr boost::shared_ptr;
class A {
public:
virtual void sing() = 0;
protected:
virtual ~A()
{
}
};
class B : public A
{
public:
void sing()
{
cout << "A B C D E \n\n" << endl;
};
};
static boost::shared_ptr<A> createA()
{
boost::shared_ptr<B> p(new B());
return p;
}
typedef std::vector<boost::shared_ptr<A>> sv;
typedef boost::shared_ptr<B> SB;
typedef sv::iterator sbi;
//using namespace std;
using namespace boost;
using namespace std;
int main(int argc, char ** argv)
{
#if SCOPED_PTR
scoped_ptr<string> st(new string("Scoped ptr Inner Text"));
//错误的做法,scoped_ptr 不能复制
//st = new scoped_ptr<string>;
cout << *st <<endl<<"Is "<<st->size()<<" length"<<endl;
*st = "文本已经改变!"; //但是scoped指针指向的内容是可以改变的,scoped_ptr 使用与普通指针没有区别!
cout << endl << *st;
#endif // SCOPED_PTR
#if SHARED_SIMPLE
sv shared_v;
for (int i = 0; i < 100; i++)
{
shared_v.push_back(createA());
}
cout << "下面取出并打印:\n";
for (auto a: shared_v)
{
a->sing();
}
#endif
#if SHARED_FILE
fstream fs("1.txt",ios::out|ios::out);
if (!fs.bad())
{
boost::shared_ptr<std::fstream> file(&fs,filecloser());
file->write("文件内读写!\n",60);
}
#endif
cin.get();
return 0;
}
.pro文件为工程文件
.pro.user 特定环境的编译的工程文件
hello World 代码
#include <QWidget>
//窗口类
#include <QPushButton>
//按钮
int main (int argc,char** argv)
{
QApplication app(argc,argv);
QWidget w;
// w为窗口对象
QPushButton bt;
bt.setText("点击我啊啊啊啊");
// 按钮也是个窗口 ,控件都是窗口
bt.setParent(&w);
// 窗口对象的父子关系影响着显示位置
// 没有父窗口的窗口称之为主窗口
QObject::connect(&bt,SIGNAL(clicked()),&w,SLOT(close()));
// QT 对C++的扩展 ,和C++ std::bind 和 std::function 有相似之处
w.show();
// bt.show();
// 显示窗口
w.setWindowTitle("Hello ,My first QT Program!");
return app.exec();
}
#include <QApplication>
//应用程序抽象类
#include <QWidget>
//窗口类
#include <QLineEdit>
#include <QPushButton>
//按钮
int main(int argc,char** argv)
{
QApplication app(argc,argv);
QWidget w;
QLineEdit ql;
ql.setEchoMode(QLineEdit::Password);
ql.setParent(&w);
ql.setPlaceholderText("请输入密码!");
// QCompleter cp1(QStringList()<<"aaa"<<"bbb"<<"2333");
// ql.setCompleter(&cp1);
w.show();
// 显示窗口
w.setWindowTitle("Hello ,My first QT Program!");
return app.exec();
}
#include <QApplication>
//应用程序抽象类
#include <QWidget>
//窗口类
#include <QLineEdit>
#include <QPushButton>
//按钮
//#include <QBoxLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
int main(int argc,char** argv)
{
QApplication app(argc,argv);
QWidget w;
QLineEdit ql;
ql.setEchoMode(QLineEdit::Password);
ql.setParent(&w);
ql.setPlaceholderText("请输入密码!");
// ql.setGeometry(100,100,100,50);
QPushButton qp;
qp.setText("nimei");
qp.setParent(&w);
#if 0
QVBoxLayout qbb;
// QHBoxLayout qbb;
qbb.stretch(1);
qbb.addWidget(&ql);
qbb.addSpacing(50);
qbb.addWidget(&qp);
qbb.stretch(1);
#endif
QGridLayout qbb;
qbb.addWidget(&ql,1,1);
qbb.addWidget(&qp,1,2);
qbb.addWidget(new QPushButton,2,1);
qbb.addWidget(new QPushButton,2,2);
qbb.addWidget(new QPushButton,3,1);
qbb.addWidget(new QPushButton,3,2);
qbb.setColumnStretch(0,1);
qbb.setColumnStretch(3,1);
qbb.setRowStretch(0,1);
qbb.setRowStretch(4,1);
// QCompleter cp1(QStringList()<<"aaa"<<"bbb"<<"2333");
// ql.setCompleter(&cp1);
w.setLayout(&qbb);
// 设置layout
w.show();
// 显示窗口
w.setWindowTitle("Hello ,My first QT Program!");
return app.exec();
}
#ifndef DWIN_H
#define DWIN_H
#include <QWidget>
#include <QPushButton>
class DWin : public QWidget
{
Q_OBJECT
public:
explicit DWin(QWidget *parent = nullptr);
bool event(QEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void closeEvent(QCloseEvent *event);
void showEvent(QShowEvent *event);
void hideEvent(QHideEvent *event);
QPushButton *pb;
signals:
public slots:
};
#endif // DWIN_H
#include <iostream>
#include <QApplication>
#include <QEvent>
#include <QDebug>
#include <QMouseEvent>
#include <QKeyEvent>
DWin::DWin(QWidget *parent) : QWidget(parent)
{
this->setMouseTracking(true);
pb=new QPushButton("OK",this);
pb->setDefault(true);
//Lamda 表达式。。。。
connect(pb,&QPushButton::clicked,[](){
qDebug()<<"OK Pushed ............";
});
}
/*
* QAppkication 先得到消息 -》具体负责每个窗口的event()获取-》具体负责每项消息处理的虚函数
*我们可以做的:
* 1》可以重载具体的虚函数来实现自己的功能
* 2》可以重载event() 函数用来处理或者截取消息
*/
// event 管理所有的消息,用来截断所有消息 return ture ; 就能截取消息
bool DWin::event(QEvent *event)
{
return QWidget::event(event);
}
void DWin::mouseReleaseEvent(QMouseEvent *event)
{
qDebug()<<"Your mouse have been release!";
}
void DWin::mousePressEvent(QMouseEvent *event)
{
QPoint pt=event->pos();
qDebug()<<pt;
if (event->button() == Qt::LeftButton)
{
qDebug()<<"Left button have been pressed!";
}
if(event->modifiers() == Qt::ShiftModifier)
{
qDebug()<<"Shift Pressed LOL...";
}
}
void DWin::keyPressEvent(QKeyEvent *event)
{
//返回大写的字母ASCII代码!
auto mod=event->modifiers();
auto key=event->key();
qDebug()<<(char)key<<" "<<mod;
}
void DWin::keyReleaseEvent(QKeyEvent *event)
{
}
void DWin::mouseMoveEvent(QMouseEvent *event)
{
static long i;
//默认的是鼠标按下后移动
//设置窗口类 setMouseTracking(true) 后可实现鼠标不按下就接受移动消息!
qDebug()<<"mouse Moved"<<i++;
}
void DWin::closeEvent(QCloseEvent *event)
{
qDebug()<<"Closed Window";
}
void DWin::showEvent(QShowEvent *event)
{
qDebug()<<"showing Window";
}
void DWin::hideEvent(QHideEvent *event)
{
qDebug()<<"hidding Window";
}
int main (int argc ,char ** argv)
{
QApplication app(argc,argv);
DWin w;
w.show();
return app.exec();
}
首先需要安装EventFilter .经过这个控件的消息都必须经过这个过滤器
代码示例:
#ifndef DWIDGET_H
#define DWIDGET_H
#include <QWidget>
class dWidget : public QWidget
{
Q_OBJECT
public:
explicit dWidget(QWidget *parent = nullptr);
bool eventFilter(QObject *watched, QEvent *event);
QObject* _ob;
signals:
public slots:
};
# endif // DWIDGET_H
#include <QApplication>
#include <QEvent>
#include <QPushButton>
#include <QDebug>
#include "dwidget.h"
dWidget::dWidget(QWidget *parent) : QWidget(parent)
{
QPushButton* pb=new QPushButton("lalal");
pb->setParent(this);
connect(pb,SIGNAL(clicked(bool)),this,SLOT(close()));
_ob=pb;
pb->installEventFilter(this);
}
bool dWidget::eventFilter(QObject *watched, QEvent *event){
if( watched== (QObject*)_ob && (event->type()==QEvent::MouseButtonPress
|| event->type()==QEvent::MouseButtonDblClick))
{
qDebug()<<"Msg have been catched!\n an Never exit!!......";
return true;
}
return QWidget::eventFilter(watched,event); //必须返回给Qwidget
}
int main (int argc,char ** argv)
{
QApplication ap(argc,argv);
dWidget* dd=new dWidget();
dd->show();
return ap.exec();
}
ap.postEvent(dd,new QEvent(QEvent::User)); //postEvent 加入消息队里等待处理
ap.sendEvent(dd,new QEvent(QEvent::User)); //发送给消息队列并立即处理
示例代码见最后
qApp 是全局指针。可以全局调用
#ifndef APP_H
#define APP_H
#include <QApplication>
#include <QDebug>
class APP : public QApplication
{
Q_OBJECT
public:
APP(int argc,char** argv):QApplication(argc,argv)
{
}
QWidget* topW;
bool notify(QObject *, QEvent *);
};
#endif // APP_H
#include "app.h"
bool APP::notify(QObject *ob, QEvent *ev)
{
if(this->topLevelWidgets().count()>0)
{
topW=this->topLevelWidgets().at(0);
if(ob==(QObject*)topW && ev->type() ==QEvent::MouseButtonPress)
{
qDebug()<<"main window is clicked";
}
}
return QApplication::notify(ob,ev);
}
#ifndef DWIDGET_H
#define DWIDGET_H
#include <QWidget>
class dWidget : public QWidget
{
Q_OBJECT
public:
explicit dWidget(QWidget *parent = nullptr);
bool eventFilter(QObject *watched, QEvent *event);
QObject* _ob;
bool event(QEvent *event);
signals:
public slots:
};
#endif // DWIDGET_H
//#include <QApplication>
#include <QEvent>
#include <QPushButton>
#include <QDebug>
#include "dwidget.h"
#include "app.cpp"
dWidget::dWidget(QWidget *parent) : QWidget(parent)
{
QPushButton* pb=new QPushButton("lalal");
pb->setParent(this);
connect(pb,SIGNAL(clicked(bool)),this,SLOT(close()));
_ob=pb;
pb->installEventFilter(this);
}
bool dWidget::eventFilter(QObject *watched, QEvent *event){
if( watched== (QObject*)_ob && (event->type()==QEvent::MouseButtonPress
|| event->type()==QEvent::MouseButtonDblClick))
{
qDebug()<<"Msg have been catched!\n an Never exit!!......";
return true;
}
return QWidget::eventFilter(watched,event);
}
bool dWidget::event(QEvent *event)
{
if(event->type()==QEvent::User)
{
qDebug()<<"User Event is comming";
}
return QWidget::event(event);
}
int main (int argc,char ** argv)
{
APP ap(argc,argv);
dWidget* dd=new dWidget();
dd->show();
//发送一个Event 给 dWidget
ap.postEvent(dd,new QEvent(QEvent::User)); //postEvent 加入消息队里等待处理
ap.sendEvent(dd,new QEvent(QEvent::User)); //发送给消息队列并立即处理
return ap.exec();
}
通过定义 PaintDevice 然后在 PainDevice 中画,然后再显示
可以通过 Qpainter 实现 一个自定义的画图工具
代码如下:
#ifndef WW_H
#define WW_H
#include <QApplication>
#include <QPainter>
#include <QEvent>
#include <QWidget>
#include <QMouseEvent>
class ww : public QWidget
{
Q_OBJECT
public:
explicit ww(QWidget *parent = nullptr);
// void Pain()
// {
// p->drawLine(QPoint(0,0),QPoint(0,100));
// p->drawRect(QRect(QPoint(50,50),QPoint(200,100)));
// }
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
QVector<QVector<QPoint>>_lines; //用Qvector 记录连起来的点是line ,——lines 则是这些线的集合
void paintEvent(QPaintEvent*);
signals:
public slots:
};
#endif // WW_H
#include "ww.h"
ww::ww(QWidget *parent) : QWidget(parent)
{
// QPaintDevice* qd=new QPaintDevice();
}
void ww::paintEvent(QPaintEvent* e)
{
QPixmap* map=new QPixmap(size());
map->fill(Qt::gray);
//QPainter* p=new QPainter(this);
QPainter* p=new QPainter(map);
p->setBackground(QBrush(QColor(Qt::gray)));
p->setBrush(Qt::red);
p->setPen(QPen(Qt::green));
p->translate(50,50);
QTransform* trans=new QTransform;
trans->rotate(30);
trans->scale(0.3,0.3);
p->setTransform(*trans);
p->drawLine(QPoint(0,0),QPoint(100,100));
p->drawRect(QRect(QPoint(50,50),QPoint(200,100)));
p->drawText(QPoint(100,100),"Hello 你好");
p->drawPixmap(QPoint(200,200),QPixmap("11.png"));
p->end(); //在 PixMAp 绘画结束
p->begin(this); //重新开始在屏幕上画
p->drawPixmap(QPoint(0,0),*map); //重新在窗口中显示图片
p->setBrush(Qt::black);
p->setPen(QPen(Qt::black));
// 下面为定义 划线的函数
for(int x=0;x<_lines.size();x++)
{
const QVector<QPoint>& line = _lines.at(x);
for (int i=0;i<line.size()-1;i++)
{
p->drawLine(line.at(i),line.at(i+1));
}
}
}
void ww::mouseMoveEvent(QMouseEvent *event)
{
QVector<QPoint>& lastLine=_lines.last();
lastLine.append(event->pos());
update(); //重绘窗口,隐含调用PaintEvent
}
void ww::mousePressEvent(QMouseEvent *event)
{
QVector<QPoint> line;
_lines.append(line);
QVector<QPoint>& lastLine=_lines.last();
lastLine.append(event->pos());
}
void ww::mouseReleaseEvent(QMouseEvent *event)
{
QVector<QPoint>& lastLine=_lines.last();
lastLine.append(event->pos());
}
int main (int argc,char** argv)
{
QApplication app(argc,argv );
ww* window=new ww();
// window->Pain();
window->show();
return app.exec();
}
模块对话框和普通对话框:
有很多特殊的 Dialog 如打印(预览) ,文件选择,MessageBox,颜色选择,字体选择
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QPushButton>
#include <QDebug>
#include <QFileDialog>
#include <QString>
#include <QFileInfo>
#include <QFontDialog>
#include <QMessageBox>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:s
explicit Dialog(QWidget *parent = 0);
~Dialog();
signals:
public slots:
void _clicked()
{
#if 0
QDialog* qd=new QDialog();
// qd->setParent(this); //不能设置Parent。。。
qDebug()<<"Clicked";
QPushButton* qpp=new QPushButton("Accept",qd);
connect(qpp,SIGNAL(clicked(bool)),qd,SLOT(accept()));
int rect;
if(rect=qd->exec() == QDialog::Accepted) //exec() 显示是个模块对话框 只能有一个
{
qDebug()<<"Accept";
}
if(rect==QDialog::Rejected)
{
qDebug()<<"Rejected";
}
// qd->show(); //show() 显示,是正常对话框 可以有无数个
#endif
#if 0
QString Filename =
QFileDialog::getSaveFileName(NULL,"Slect File for save",_str,"PNG File(*.png)"); //QFIleDialog 一般直接直接使用静态函数 getOpenFileName 指定打开文件
qDebug()<<Filename;
QFileInfo FileInfo(Filename);
_str=FileInfo.path();
QFontDialog* font=new QFontDialog(this);
font->exec();
qDebug()<<font->selectedFont();
#endif
QMessageBox::warning(this,"警告","警告@!!!!");
}
private:
Ui::Dialog *ui;
QString _str;
};
#endif // DIALOG_H
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
QPushButton* pb=new QPushButton("new one");
pb->setParent(this);
ui->setupUi(this);
connect(pb,SIGNAL(clicked(bool)),this,SLOT(_clicked()));
}
Dialog::~Dialog()
{
delete ui;
}
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>946</width>
<height>560</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
主窗口
菜单栏 : Qmenu 菜单类 QMenuBar 菜单栏 QAction 菜带项目
Status Bar
Tool Bar
QSystemTrayIcon 系统托盘类
示例代码如下:
#ifndef MW_H
#define MW_H
#include <QMainWindow>
#include <QApplication>
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QList>
#include <QFileDialog>
#include <QString>
#include <QDebug>
#include <QToolBar>
#include <QStatusBar>
#include <QLabel>
#include <QSystemTrayIcon> //系统托盘类
#include "mview.h"
class mw : public QMainWindow
{
Q_OBJECT
public:
mw(QWidget *parent = 0);
~mw();
private:
QString _str;
mview* _view;
QMenu* _menu;
QSystemTrayIcon* _icon;
public slots:
void open_file()
{
_str=QFileDialog::getOpenFileName(this,"",_str,"TXT File (*.txt)");
qDebug()<<"Opened File :"<<_str;
}
void open_dir()
{
_str=QFileDialog::getExistingDirectory(this,"",_str);
qDebug()<<"Opened Directory :"<<_str;
}
// void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
bool event(QEvent *event);
signals:
void clicked();
};
#endif // MW_H
#include "mw.h"
mw::mw(QWidget *parent)
: QMainWindow(parent)
{
//加菜单
QMenuBar* menubar=this->menuBar(); //获取mainWindow 里面的MenuBar
QMenu* menu=menubar->addMenu("&Open"); //通过MenuBar 添加菜单,每个菜单对弈一个菜单项
QAction* open_file=new QAction("Open File");
QAction* open_Directory=new QAction("Open Directory");
QAction* exit_this=new QAction("Exit");
// QAction* blank=new QAction("Exit");
exit_this->setShortcut(QKeySequence::Quit);
open_file->setShortcut(QKeySequence::Open);
connect(exit_this,SIGNAL(triggered(bool)),this,SLOT(close())); //绑定槽函数,信号使用trggered()
connect(open_file,SIGNAL(triggered(bool)),this,SLOT(open_file()));
connect(open_Directory,SIGNAL(triggered(bool)),this,SLOT(open_dir()));
QList<QAction*> ql={
open_file,
open_Directory,
exit_this
};
menu->addActions(ql);
_menu =menu;
// ToolBar
QToolBar* tb1= this->addToolBar("TollBar");
tb1->addActions(ql);
//Status Bar
QStatusBar* stb=this->statusBar();
stb->addWidget(new QLabel("OK"));
stb->addActions(ql);
_view = new mview;
this->setCentralWidget(_view);
this->setWindowOpacity(0.9); //设置 窗口透明度 小数
//创建托盘类
_icon=new QSystemTrayIcon(this);
_icon->setIcon(QIcon("E:/code/universal/QT/MW/1.ico"));
_icon->setToolTip("我是Elliot 的小程序的哦");
_icon->show();
}
//void mw::paintEvent(QPaintEvent *event)
//{
//}
void mw::mousePressEvent(QMouseEvent *event)
{
if(event->button()==Qt::RightButton)
_menu->exec(QCursor::pos());
}
bool mw::event(QEvent *event)
{
if(event->type()==QEvent::Close)
{
return true;
}
return QMainWindow::event(event);
}
mw::~mw()
{
}
#ifndef MVIEW_H
#define MVIEW_H
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
#include <QPixmap>
class mview : public QWidget
{
Q_OBJECT
public:
explicit mview(QWidget *parent = nullptr){}
void paintEvent(QPaintEvent *event)
{
QPainter* panter=new QPainter(this);
panter->fillRect(rect(),Qt::black);
panter->drawArc(50,50,30,30,10,50);
panter->drawPixmap(QPoint(0,0),QPixmap("E:/code/universal/QT/MW/11.png"));
}
signals:
public slots:
};
#endif // MVIEW_H
#include "mview.h"
mview::mview(QWidget *parent) : QWidget(parent)
{
}
#include "mw.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
mw w;
w.show();
return a.exec();
}
#ifndef MW_H
#define MW_H
#include <QWidget>
#include <QApplication>
#include <QFile>
#include <QBuffer>
#include <QTextBrowser>
#include <QPixmap>
#include <QLabel>
#include <QTextStream>
#include <QDataStream>
class mw : public QWidget
{
Q_OBJECT
public:
explicit mw(QWidget *parent = nullptr);
signals:
public slots:
};
#endif // MW_H
#include "mw.h"
mw::mw(QWidget *parent) : QWidget(parent)
{
QTextBrowser* qbb=new QTextBrowser(this);
QFile file("devil.txt");
file.open(QFile::ReadWrite);
file.write("jaingnan");
file.close();
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
#if 0
buffer.write("aa");
// QString aa(‘江南的风‘);
buffer.write("Nothing to read");
#endif
QPixmap* map=new QPixmap("11.png");
map->save(&buffer,"png");
qbb->setText(buffer.buffer());
QString str=tr("%1").arg(buffer.size());
qbb->append(str);
buffer.close();
QPixmap* png=new QPixmap;
png->loadFromData(buffer.buffer(),"PNG");
const QPixmap png1=*png;
QLabel* label=new QLabel(this);
label->setPixmap(png1);
//Text Stream
QFile file1("stream.txt");
file1.open(QFile::ReadWrite);
QTextStream qs(&file1);
qs<<"nimeide"<<1.2<<22;
file.close();
//虚拟内存 Virtual Memory
}
int main (int argc,char ** argv)
{
QApplication app(argc,argv);
mw* mw1=new mw();
mw1->show();
return app.exec();
}
LIBS += LE:\code\universal\QT\build-Library-Desktop_Qt_5_14_1_MSVC2017_32bit-Debug\debug -lLibrary
LIBS += L库的目录 -l库的名称
LIBS += -LC:\Qt\Qt5.14.1\5.14.1\Src\qtbase\src\plugins\sqldrivers\mysql -lmysql INCLUDEPATH +="C:/Program Files (x86)/MySQL/MySQL Connector C 6.1/include" QMAKE_LIBDIR +="C:/Program Files (x86)/MySQL/MySQL Connector C 6.1/lib"
C:\Qt\Qt5.14.1\5.14.1\msvc2017\bin\qmake -- MYSQL_INCDIR="C:\Program Files (x86)\MySQL\MySQL Connector C 6.1\include" MYSQL_LIBDIR="C:\Program Files (x86)\MySQL\MySQL Connector C 6.1\lib"
原文:https://www.cnblogs.com/dev995/p/Elliot.html