写在前面
首先,我也是一个C++的“初学者”,时常痛恨自己没有系统的C++理论体系、理论基础。所以下面的一些分享是自己的一些“经验”或者“心得”,属于主观认识。希望给大家以参考。文章适合比我还菜的小白。
全局变量的意义
意义太大了。因为在C++的工程中,我们面向对象编程会创造一个个类(A Class,B Class,C Class等等)。一般来说我们为这些类又会设置不同的.cpp和.h(A.cpp,A.h;B.cpp,B.h等等)
这些类实现的功能是不同的,本来没有什么交集。
但是 往往会有那么一个变量(注意是变量 而不是某个类)会同时在好多类中用到。
举个例子,我在A功能中需要使用一个变量var,经过A功能的的流程后,var的值改变了,这时候我们又要使用B功能,我们希望B功能中的这个变量var是经过A之后变化过后的var。
区分
这边要进行一个区分,因为我们可以看出全局变量的意义在于“共用”。在C++中,有另一种方法也可以使不同类共用一个变量。就是使用变量的传递方法,我们一般是这么写的:
#A.cpp# #里面都编写一些A类的成员函数#
m_layerTreeView->setMenuProvider( new QGISEditLayerTreeViewMenuProvider( m_layerTreeView, m_mapCanvas) );
我们可以看出 在A类中,通过这行代码,就可以把 m_layerTreeView, m_mapCanvas两个A类的成员变量给传给QGISEditLayerTreeViewMenuProvider这个新的类了。然后我们可以在QGISEditLayerTreeViewMenuProvider中的成员函数进行对着两个变量的操作。
这个函数传递的方法有什么缺陷?
答:这种传递过程是单向的。在这行代码执行完后,假如m_layerTreeView, m_mapCanvas在A类的其他成员函数中被操作了,对应的QGISEditLayerTreeViewMenuProvider类中的这两个变量的值是不会变的。
所以,要达到变量在不同类中的同时变化,就需要声明一个全局变量。
声明过程
写这篇博客的一个原因就是,网上就算说了声明全局变量的代码,也只是给了那一句代码,那这个代码该写在什么位置呢?
A类的头文件
A类的.h文件,当然这里实际是 QGisEdit.h
#ifndef QGISEdit_H
#define QGISEdit_H
#include <QMainWindow> #include的位置
class QgsMessageBar; #其他各种类的位置
//主角的位置在这里!!!mapCanvasLayerSet就是我们的全局变量!!
//QList<QgsMapLayer *> 是这个全局变量的数据类型 就好比 int,double之类的
extern QList<QgsMapLayer *> mapCanvasLayerSet ; // 地图画布所用的图层集合 让它成为全局变量
//以下是对A这个类的成员函数的声明或定义,全局变量不能和他们在一起
class QGISEdit : public QMainWindow
{
Q_OBJECT
public:
QGISEdit(QWidget *parent = 0, Qt::WindowFlags flags = 0);
~QGISEdit();
省略各种private: public slots:的内容
};
//全局变量在这里也可以声明,即在A类声明的括号“}”之外!
extern QList<QgsMapLayer *> mapCanvasLayerSet ;
#endif
A类的源文件(.cpp)
那我们要不要在A类的源文件A.cpp中对这个全局变量mapCanvasLayerSet进行什么操作呢?
答案是 可以不用!!
如果你在A.cpp中根本没有用到这个变量,就没必要去多写了,也不用在A.cpp中进行初始化
B类的头文件(.h)
不用进行任何操作!!
B类的源文件(.cpp)
我们在A类中定义好了全局变量mapCanvasLayerSet,现在想在B类的文件中(B.cpp)中进行使用。
只有两步:
- 开头声明
- 函数中直接使用
#### B.cpp #####
#include"A.h"
#对其他头文件的include
//在开头声明一下全局变量!!!!
QList<QgsMapLayer *> mapCanvasLayerSet;
//下面是B类的一些初始化操作
classB::QGISEditLayerTreeViewMenuProvider(QgsLayerTreeView *view, QgsMapCanvas* canvas)
: mView(view)
, mCanvas(canvas)
{
}
classB::~classB()
{
}
//要用到全局变量的B类的一个函数functionB,直接使用mapCanvasLayerSet这个全局变量
void classB::functionB()
{
、、、、其他一些代码、、、、
mapCanvasLayerSet.removeAt(selectedLayerPos);
qDebug() << mapCanvasLayerSet;
}
其他的一些B类的成员函数
到这里 大功告成!!
补充说明
如果在那两步走中,没有在B类的源文件(B.cpp)进行开头声明,
#### B.cpp #####
#include"A.h"
#对其他头文件的include
//在开头声明一下全局变量!!!! 如果没有声明 会怎么样??
QList<QgsMapLayer *> mapCanvasLayerSet;
会报一个错(当时我就是没有进行开头声明)
如果报这个错的兄弟,可以看看自己是否犯了如上的错误