在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序,也就是所有的源文件,包括 .c 和 .h 文件。

在C++中,我们可以使用静态成员变量来实现多个对象共享数据的目标。静态成员变量是一种特殊的成员变量,它被关键字static修饰


如果在函数体内部修改了全局包括的值,那么会在函数体内部临时创建一个局部变量保存当前等号右边的值,所以当调用函数结束返回主程序时,或是在其他函数里面使用到这个全局变量时,全局变量的值都是不变的,很明显,这是一个值得注意的细节。

在这里我们去修改全局变量的值:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int sum = 0;
void f(int n) {
    sum += n;
}

void print_res(vector<int> v) {
    for_each(v.begin(), v.end(), f);
    cout << "sum = " << sum << endl;
}

int main() {
    vector<int> v;
    for (int i = 0; i <= 100; i++) {
        v.push_back(i);
    }
    print_res(v);
    return 0;
}

c++为什么不使用全局变量和静态成员变量以及解决方法_全局变量

全局变量和静态成员变量对于整个程序时共享数据的,如果我们通过多线程去修改同一个值会发生什么呢?

#include <iostream>
#include <vector>
#include <algorithm>
#include <thread>
using namespace std;
int sum = 0;
void f(int n) {
        sum += n;
}
void print_res(vector<int> v) {
        for_each(v.begin(), v.end(), f);
        cout << "sum = " << sum << endl;
}
int main() {
        vector<int> v;
        for (int i = 0; i <= 100; i++) {
               v.push_back(i);
        }
        for (int i = 0; i < 10; i++) {
        thread th1(print_res, ref(v));
        thread th2(print_res, ref(v));
        th1.join();
        th2.join();
    }
        return 0;
}

c++为什么不使用全局变量和静态成员变量以及解决方法_静态变量_02

这里引入间接依赖:当A和B同时调用globle sum,A修改了sum值,B所调用的sum就会产生不可预期的变化,即A和B形成间接依赖。

这将导致出现不可控的结果,使用函数对象可以避免使用全局和静态的变量,

得出结论:如果我们将全局变量封装到一个CSum()类中就可以避免间接依赖的出现。

最后一点:如果我们将上面sum变量和f()函数封装到一个类中是否可以调用for_each()函数:

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;

template<typename T>
class CSum {
private:
    T sum{};
public:
    CSum() {}
    void f(T n) {
        sum += n;
    }
    T getSum() {
        return sum;
    }
};

int main() {
    vector<int> v{ 10, 98, 50, 34, 70 };
    
    CSum<int> c = for_each(v.begin(), v.end(), c.f);
    cout << c.getSum() << endl;
    return 0;
}

c++为什么不使用全局变量和静态成员变量以及解决方法_静态变量_03

可知for_each()第三个参数对非静态成员函数(即无法使用类中封装的成员函数)的使用无效:

稍作修改:

int main() {
    vector<int> v{ 10, 98, 50, 34, 70 };
    CSum<int> c;
    for (int i = 0; i < v.size(); ++i)
        c.f(v[i]);
    cout << c.getSum() << endl;
    return 0;
}

c++为什么不使用全局变量和静态成员变量以及解决方法_静态变量_04

得出结论:如果我们重载operator()操作符,那么在for_each()函数中直接采用构造函数形式调用即可避免问题。