自定义两个类
class OnePiece {
public:
OnePiece() {
qDebug() << QString("构造OP");
}
~OnePiece() {
qDebug() << QString("~析构OP");
}
public:
void print() {
qDebug() << QString("OP在拉夫德鲁");
}
};
class Nika : public QObject {
public:
Nika() {
qDebug() << "构造尼卡";
}
~Nika() {
qDebug() << "析构尼卡";
}
public:
void print() {
qDebug() << "这个时代,路飞是尼卡";
}
};
QSharedPointer && QWeakPointer
- QSharedPointer
- 共享指针
- 强引用
- 线程安全
- 内部采用引用计数,引用计数的原子机制的
- 引用计数为0时,释放对象,删除原生指针
- QWeakPointer
- 线程安全
- 弱引用
- 不增加引用计数
- 不能调用原生指针对象方法(没有重载operator*和->)
- 配合QSharedPointer使用,解除循环引用问题
// QSharedPointer + QWeakPointer
qDebug() << "QSharedPointer Example Start...";
//case1 引用计数
{
QSharedPointer<OnePiece> op1 = QSharedPointer<OnePiece>(new OnePiece); //引用计数为1
QSharedPointer<OnePiece> op2(op1); //引用计数为2
QSharedPointer<OnePiece> op3 = op1; //引用计数为3
op3->print();
// 弱引用
QWeakPointer<OnePiece> op4 = op1; //引用计数为3
// 弱引用转为强引用
QSharedPointer<OnePiece> op5 = op4.toStrongRef(); //引用计数为4
QSharedPointer<OnePiece> op6 = op4.lock(); //引用计数为5
op6->print();
}
//case2 取出原生指针(不建议取出原生指针操作)
{
QSharedPointer<OnePiece> op = QSharedPointer<OnePiece>(new OnePiece); //引用计数为1
OnePiece *op1 = op.data();
op1->print();
OnePiece *op2 = op.get();
op2->print();
}
//case3 清除对象 解除对原生指针的引用,若为最后一个引用,则删除对象
{
QSharedPointer<OnePiece> op1 = QSharedPointer<OnePiece>(new OnePiece); //引用计数为1
QSharedPointer<OnePiece> op2(op1); //引用计数为2
op2.clear(); //引用计数为1
if (op2.isNull()) {
qDebug() << "op2 is null";
}
}
qDebug() << "QSharedPointer Example End...";
QScopedPointer
- 独享指针(没有拷贝构造和赋值构造接口)
- 没有引用计数
- 线程安全
// QScopedPointer
qDebug() << "QScopedPointer Example Start...";
// case1 独享指针
{
QScopedPointer<OnePiece> op(new OnePiece);
op->print();
}
// case2 使用例子
{
auto func1 = [](int i){
OnePiece *op = new OnePiece;
if (i < 5) {
delete op; //不方便管理,这个位置可能会忘记delete
return;
}
op->print();
delete op;
return ;
};
auto func2 = [](int i){
QScopedPointer<OnePiece> op(new OnePiece);
if (i < 5) {
return;
}
op->print();
return;
};
}
// case3 取出原生指针
{
QScopedPointer<OnePiece> op(new OnePiece);
OnePiece *op1 = op.data(); //op扔持有对象
OnePiece *op2 = op.get(); //op扔持有对象
qDebug() << (op.isNull() ? "op is null" : "op is not null");
OnePiece *op3 = op.take(); //op为null
qDebug() << (op.isNull() ? "op is null" : "op is not null");
// 错误例子
auto fun = []()->OnePiece * {
QScopedPointer<OnePiece> op1(new OnePiece);
op1->print();
return op1.data();
// OnePiece op1;
// op1.print();
// return &op1;
};
OnePiece *op7 = fun(); //fun()中op1被析构,所以会delete原生指针,所以op7会成为悬挂指针
op7->print(); //测试后正常输出,有点奇怪???
}
qDebug() << "QScopedPointer Example End...";
QPointer
- 只能使用于继承自QObject的类
- 如果多个QPointer同时指向同一个对象,其中一个被delete,其它的QPointer则会被置为nullptr,避免了成为野指针的情况
// QPointer
qDebug() << "QPointer Example Start...";
{
QPointer<Nika> nika1(new Nika);
QPointer<Nika> nika2 = nika1;
if (!nika1.isNull()) {
nika1->print();
}
nika1.clear();
if (nika1.isNull()) {
qDebug() << "nika1 is null";
}
if (!nika2.isNull()) {
nika2->print();
}
QPointer<Nika> nika3 = nika2;
delete nika2; //nika2被delete后,nika3也会被置为nullptr
if (nika3.isNull()) {
qDebug() << "nika3 is null";
}
}
qDebug() << "QPointer Example End...";
QScopedArrayPointer
- 使用于数组对象
// QScopedArrayPointer
qDebug() << "QScopedArrayPointer Example Start...";
{
QScopedArrayPointer<OnePiece> ops(new OnePiece[3]);
ops[0].print();
//OnePiece op = ops[1];
//op.print();
}
qDebug() << "QScopedArrayPointer Example End...";
QSharedDataPointer
- 方便实现隐式共享类
- 待补充
QExplicitlySharedDataPointer
- 方便实现显示共享类
- 待补充
Sevenlin++
目前在平时编码过程中基本不使用智能指针,还是在使用原生指针,这一点需要改进。有这么好的方式来管理指针,不用白不用,也可以避免指针管理不当造成的内存泄露。