系统中全局变量的一种使用方式:类的静态成员变量
tip:静态成员变量在类内定义变量,类外初始化
common.h
#ifndef COMMON_H
#define COMMON_H
#include
#include
#include
#include
#define qdebug qDebug()<<"FILE("<<__FILE__<<") LINE("<<__LINE__<<") FUNC("<<__FUNCTION__<<")"
//Execl模块路径
#define EXECLTEMPLATEPATH QApplication::applicationDirPath() + "/config/"
class common : public QObject
{
Q_OBJECT
public:
explicit common(QObject *parent = 0);
static void downLoadExcelTemplate(QWidget* parent,QString fileName);
static void downLoadFileFromSomeDir(QWidget *parent, QString path, QString srcFileName, QString toFileName="");
static bool deleteDirectory(const QString path); //删除非空文件夹
static QString getFileMd5(QString filePath);
static bool copyFileToPath(QString sourceFileAbsPath , QString toFileAbsPath);
//当前选中的任务信息
static QString project;//全局变量 选中的专项名称
static QString task;//全局变量 选中的任务名称
static QString task_code;//全局变量 选中的编号
static QString undertake;//全局变量 选中的任务承担单位
static QString participant;//全局变量
static QString ship;
static QString leader;//任务负责人
static QString chief_scientist;//全局变量 首席科学家
static QString userName;
static QString userDepartment;
static QString userRole;
signals:
public slots:
};
#endif // COMMON_H
common.cpp
#include "common.h"
#include
#include
#include
#include
#include "mymessagebox.h"
#include
QString common::project="";//全局变量 选中的项目
QString common::task="";//全局变量 选中的项目
QString common::task_code="";//全局变量 选中的项目
QString common::undertake="";//全局变量 选中的项目
QString common::participant="";//全局变量 选中的项目
QString common::ship="";
QString common::leader="";//任务负责人
QString common::chief_scientist="";//全局变量 首席科学家
QString common::userName="";
QString common::userDepartment="";
QString common::userRole="";
common::common(QObject *parent) : QObject(parent)
{
}
void common::downLoadExcelTemplate(QWidget* parent,QString fileName)
{
QString path = QFileDialog::getExistingDirectory(parent, tr("选择保存路径"), "../", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if(path.isEmpty())
{
return;
}
else if(QFile::exists(QString(QApplication::applicationDirPath() + "/config/%1").arg(fileName))==false)
{
int ret = myMessageBox::warning(parent, tr("异常提示:"),QString("《%1》未在系统中找到!").arg(fileName));
}
else if(QFile::exists(QString("%1/%2").arg(path).arg(fileName))==true)
{
int ret = myMessageBox::warning(parent, tr("提示:"),QString("%1 已存在《%2》!\n\n如需下载,请更换保存路径或者重命名已有的模板!").arg(path).arg(fileName));
}
else
{
bool result=QFile::copy(QString(QApplication::applicationDirPath() + "/config/%1").arg(fileName),QString("%1/%2").arg(path).arg(fileName));
if(result)
{
int ret = myMessageBox::information(parent, tr("海洋调查现场质量监督管理系统"),tr("模板下载成功,直接打开查看模板?\n"),QMessageBox::Yes |QMessageBox::No);
if(ret==QMessageBox::Yes)
{
QAxObject *excel = NULL; //本例中,excel设定为Excel文件的操作对象
QAxObject *workbooks = NULL;
QAxObject *workbook = NULL; //Excel操作对象
excel = new QAxObject("Excel.Application");
excel->dynamicCall("SetVisible(bool)", true); //true 表示操作文件时可见,false表示为不可见
workbooks = excel->querySubObject("WorkBooks");
//按文件路径打开文件
workbook = workbooks->querySubObject("Open(QString&)",QString("%1/%2").arg(path).arg(fileName));
}
}
}
}
void common::downLoadFileFromSomeDir(QWidget *parent, QString filePath,QString srcFileName,QString toFileName)
{
QString path = QFileDialog::getExistingDirectory(parent, tr("选择保存路径"), "../", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if(path.isEmpty())
{
return;
}
else if(QFile::exists(QString("%1/%2").arg(filePath).arg(srcFileName))==false)
{
int ret = myMessageBox::warning(parent, tr("异常提示:"),QString("《%1》未在系统中找到!").arg(srcFileName));
}
else if(QFile::exists(QString("%1/%2").arg(path).arg(srcFileName))==true)
{
int ret = myMessageBox::warning(parent, tr("提示:"),QString("%1 已存在《%2》!\n\n如需下载,请更换保存路径或者重命名已有文件!").arg(path).arg(srcFileName));
}
else
{
if(toFileName=="")
{
toFileName=srcFileName;
}
bool result=QFile::copy(QString("%1/%2").arg(filePath).arg(srcFileName),QString("%1/%2").arg(path).arg(toFileName));
if(result)
{
int ret = myMessageBox::information(parent, tr("海洋调查现场质量监督管理系统"),tr("文件下载成功,进入文件夹?\n"),QMessageBox::Yes |QMessageBox::No);
if(ret==QMessageBox::Yes)
{
QDesktopServices::openUrl(QUrl("file:///"+path, QUrl::TolerantMode));
}
}
}
}
//删除非空文件夹
bool common::deleteDirectory(const QString path)
{
if (path.isEmpty())
return false;
QDir dir(path);
if(!dir.exists())
return true;
dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
QFileInfoList fileList = dir.entryInfoList();
foreach (QFileInfo fi, fileList)
{
if (fi.isFile())
fi.dir().remove(fi.fileName());
else
deleteDirectory(fi.absoluteFilePath());
}
return dir.rmpath(dir.absolutePath());
}
QString common::getFileMd5(QString filePath)
{
QFile file(filePath);
file.open(QIODevice::ReadOnly);
QByteArray ba=QCryptographicHash::hash(file.readAll(), QCryptographicHash::Md5);
file.close();
return QString(ba.toHex().constData());
}
bool common::copyFileToPath(QString sourceFileAbsPath, QString toFileAbsPath)
{
toFileAbsPath.replace("\\","/");
if (sourceFileAbsPath == toFileAbsPath){
return true;
}
if (!QFile::exists(sourceFileAbsPath)){
return false;
}
QDir *createfile = new QDir();
bool existDir = createfile->exists(QFileInfo(toFileAbsPath).absolutePath());//如果不存在文件夹创建文件夹
if (!existDir)
{
// createfile->remove(toFileAbsPath);
createfile->mkdir(QFileInfo(toFileAbsPath).absolutePath());
}
bool toFileIsExist= createfile->exists(toFileAbsPath);//如果文件已存在,删除文件
if (toFileIsExist)
{
createfile->remove(toFileAbsPath);
// createfile->mkdir(QFileInfo(toFileAbsPath).absolutePath());
}
if(!QFile::copy(sourceFileAbsPath, toFileAbsPath))
{
qdebug<<sourceFileAbsPath;
qdebug<<toFileAbsPath;
return false;
}
return true;
}
c语言中,static既可以修饰变量(全局变量和局部变量),又可以修饰函数。static类型的变量称为静态变量,如果不初始化则编译器自动初始化为0
static的用法有两种:
1.修饰全局变量 或 函数,用于限定该变量或函数作用域为本文件。(这种限定是针对编译器而言,运行时没有区别)
2.修饰局部变量,用于修改变量的生存周期,维持持久性。
变量的作用域仍然为局部的,但是离开作用域后,静态变量不会被销毁,而是仍然驻留在内存当中,直到程序结束。
如果将静态变量的指针传出后,在作用域之外仍然可以通过指针访问这个变量。
再次调用函数的时候,这个静态变量仍然保持着上次时候的值。
对于全局变量使用static,可以多个文件中使用相同名字的全局变量而不会发生名字冲突。
这样不同的文件可以使用相同名字的函数而不会发生混淆。
c++static关键字的作用
以下是一般人都会背了的吧:
c/c++共有
1):修饰全局变量时,表明一个全局变量只对定义在同一文件中的函数可见。
2):修饰局部变量时,表明该变量的值不会因为函数终止而丢失。
3):修饰函数时,表明该函数只在同一文件中调用。
c++独有:
4):修饰类的数据成员,表明对该类所有对象这个数据成员都只有一个实例。即该实例归 所有对象共有。
5):用static修饰不访问非静态数据成员的类成员函数。这意味着一个静态成员函数只能访问它的参数、类的静态数据成员和全局变量
深究:
(1)在头文件把一个变量申明为static变量,那么引用该头文件的源文件能够访问到该变量吗。
答:可以。声明static变量一般是为了在本cpp文件中的static变量不能被其他的cpp文件引用,但是对于头文件,因为cpp文件中包含了头文件,故相当于该static变量在本cpp文件中也可以被见到。当多个cpp文件包含该头文件中,这个static变量将在各个cpp文件中将是独立的,彼此修改不会对相互有影响。
https://blog.csdn.net/qq_17368865/article/details/79110149 (这篇文章谈到了头文件中声明static的利弊)
(2)为什么静态成员函数不能申明为const
答:这是C++的规则,const修饰符用于表示函数不能修改成员变量的值,该函数必须是含有this指针的类成员函数,函数调用方式为thiscall,而类中的static函数本质上是全局函数,调用规约是__cdecl或__stdcall,不能用const来修饰它。一个静态成员函数访问的值是其参数、静态数据成员和全局变量,而这些数据都不是对象状态的一部分。而对成员函数中使用关键字const是表明:函数不会修改该函数访问的目标对象的数据成员。既然一个静态成员函数根本不访问非静态数据成员,那么就没必要使用const了
(3)为什么不能在类的内部定义以及初始化static成员变量,而必须要放到类的外部定义
答:因为静态成员属于整个类,而不属于某个对象,如果在类内初始化,会导致每个对象都包含该静态成员,这是矛盾的。参考两篇博客:
https://blog.csdn.net/jiayi_yao/article/details/50998765 https://blog.csdn.net/sevenjoin/article/details/81772792
(4)static关键字为什么只能出现在类内部的声明语句中,而不能重复出现在类外的定义中。
答:https://blog.csdn.net/wcybrain/article/details/79048052 https://blog.csdn.net/sinat_36053757/article/details/72636903 这两篇博客解释了一下。总的来说就是:如果类外定义函数时在函数名前加了static,因为作用域的限制,就只能在当前cpp里用,类本来就是为了给程序里各种地方用的,其他地方使用类是包含类的头文件,而无法包含类的源文件。
(5)为什么常量静态成员数据的初始化可以放在类内(注意:只有静态常量整型数据成员才可以在类中初始化)
答:是否可以这样理解: static数据成员在类外定义和初始化是为了保证只被定义和初始化一次,这样编译器就不必考虑类的函数里面第一个对static变量的’=’操作是赋值还是初始化了。 static const int可以在类里面初始化,是因为它既然是const的,那程序就不会再去试图初始化了。
(6)为什么静态成员函数只能访问静态成员变量。
答:1.静态成员函数只属于类本身,随着类的加载而存在,不属于任何对象,是独立存在的
2.非静态成员当且仅当实例化对象之后才存在,静态成员函数产生在前,非静态成员函数产生在后,故不能访问
3.内部访问静态成员用self::,而访问非静态成员要用this指针,静态成员函数没有this指针,故不能访问。
(7)静态成员函数与非静态成员函数的区别
答:根本区别:静态成员函数不存在this指针,不能访问非静态成员变量。https://blog.csdn.net/xiong452980729/article/details/71079827 这篇博客总结的还不错
(8)为什么要用得静态成员变量和静态成员函数
答:为了实现共享。因为静态成员函数和静态成员变量属于类,不属于类的实体,这样可以被多个对象所共享
(9)静态成员的作用、优点
答:静态成员函数主要为了调用方便,不需要生成对象就能调用。详细请看这两篇博客:https://www.cnblogs.com/jack-wangchong/p/7404748.html https://blog.csdn.net/qq_38124695/article/details/78188411