最近编程学习了一下基础知识,顺便随手记录下,文章涉及的部分内容均已标明出处。
文中涉及到的知识点如下:
- 单例模式
- 静态指针的内存释放
- 类中声明子类的声明与实现方法
- Qt的main函数正确的编写格式(记录此坑)
.h–接口文件
class MainWindow : public QMainWindow
{
Q_OBJECT
static MainWindow *m_pselfmainwin;
class Garber //垃圾自动回收--目的使m_pselfmainwin自动析构
{
public:
Garber();
~Garber();
};
static Garber garbor;
MainWindow(QWidget *parent = NULL);
~MainWindow();
public:
static MainWindow * getInstance();
}
.cpp实现文件
//静态成员类外初始化
MainWindow * MainWindow::m_pselfmainwin = NULL;
//嵌套类的静态成员类外初始化
MainWindow::Garber MainWindow::garbor = MainWindow::Garber() ;
MainWindow::Garber::Garber() //
{
};
MainWindow::Garber::~Garber() //删除静态成员变量
{
if (m_pselfmainwin!=NULL)
{
delete m_pselfmainwin ;
m_pselfmainwin = NULL;
}
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{ }
MainWindow::~MainWindow()
{ }
MainWindow * MainWindow::getInstance()
{
if (m_pselfmainwin==NULL)
{
//m_pselfmainwin = new MainWindow();
//智能指针
QScopedPointer<MainWindow> m_pselfmainwin(new MainWindow);
m_pselfmainwin->setAttribute(Qt::WA_DeleteOnClose);
m_pselfmainwin->initHmi();
}
return m_pselfmainwin;
}
main.cpp实现文件
int main(int argc ,char *argc[])
{
QScopedPointer<QApplication> app(new QApplication(argc, argv));
MainWindow *pmainWindow = MainWindow::getInstance();// 单例模式获取实例
pmainWindow->show();
return app->exec();
}
至此单例模式的静态指针销毁实现完毕!
题外话:
1.垃圾回收参看如下链接:
https://blog.csdn.net/roy1261/article/details/51425987
2.由于使用的是qt4.7.3版本的原因,在手动关闭MainWindow 窗口时出现内存访问错误的信息,原因是引用原文如下:
参看连接 https://www.devbean.net/2012/08/qt-study-road-2-hello-world/
首先,按照标准 C++ 来看这段程序。这里存在着内存泄露。当exec()退出时(也就是事件循环结束的时候。窗口关闭,事件循环就会结束),label 是没办法 delete 的。这就造成了内存泄露。当然,由于程序结束,操作系统会负责回收内存,所以这个问题不会很严重。即便你这样修改了代码再运行,也不会有任何错误。
早期版本的 Qt 可能会有问题(详见本文最后带有删除线的部分,不过豆子也没有测试,只是看到有文章这样介绍),不过在新版本的 Qt 基本不存在问题。在新版本的 Qt 中,app.exec()的实现机制确定,当最后一个可视组件关闭之后,主事件循环(也就是app.exec())才会退出,main()函数结束(此时会销毁app)。**这意味着,所有可视元素已经都关闭了,也就不存在后文提到的,QPaintDevice没有QApplication实例这种情况。**另外,如果你是显式关闭了QApplication实例,例如调用了qApp->quit()之类的函数,QApplication的最后一个动作将会是关闭所有窗口。所以,即便在这种情况下,也不会出现类这种问题。
由于是在main()函数中,当main()函数结束时,操作系统会回收进程所占用的资源,相当于没有内存泄露。不过,这里有一个潜在的问题:操作系统只会粗暴地释放掉所占内存,并不会调用对象的析构函数(这与调用delete运算符是不同的),所以,很有可能有些资源占用不会被“正确”释放。事实上,在最新版的 Sailfish OS 上面就有这样的代码:
#include <QApplication>
int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(new QApplication(argc, argv));
QScopedPointer<QQuickView> view(new QQuickView);
view->setSource("/path/to/main.qml");
...
return app->exec();
}