构造函数中的静态变量,有任何缺点或副作用吗?

时间:2010-05-29 23:11:09

标签: c++ constructor initialization static-variables

我想做什么:每当要在程序中使用类的实例时运行一些先决条件代码。此代码将检查要求等,并且只应运行一次。

我发现这可以使用另一个对象作为构造函数中的静态变量来实现。这是一个更好的图片的例子:

class Prerequisites
{
     public:
         Prerequisites() {
              std::cout << "checking requirements of C, ";
              std::cout << "registering C in dictionary, etc." << std::endl;
         }
};


class C
{
    public:
         C() {
             static Prerequisites prerequisites;
             std::cout << "normal initialization of C object" << std::endl;
         }
};

令我感到困扰的是,到目前为止我还没有看到类似的静态变量。是否有任何缺点或副作用或我遗失了什么?或者也许有更好的解决方案?欢迎任何建议。

3 个答案:

答案 0 :(得分:5)

这不是线程安全的,因为如果两个线程同时第一次尝试构造C,则先决条件可能会初始化两次。

如果你对此感到满意,你可以做到这一点,虽然游戏范围内的构造函数系统没有可发现性(即一旦你忘记'技巧'或其他人试图阅读你的代码,他们会感到困惑,因为发生了什么事。)

答案 1 :(得分:4)

  

是否有任何缺点或副作用或我遗失了什么?或者也许有更好的解决方案?欢迎任何建议。

显式调用静态方法可能更清楚(尽管更详细)。

class Prerequisites
{
    static bool checkedOnce;    
public:
    static void checkOnce() {
        if (checkedOnce)
        {
            //already checked: don't check again
            return;
        }
        //else check them now
        checkedOnce = true;
        std::cout << "checking requirements of C, ";
        std::cout << "registering C in dictionary, etc." << std::endl;
    }
};

bool Prerequisites::checkedOnce = false;

class C
{
public:
    C() {
        Prerequisites::checkOnce();
        std::cout << "normal initialization of C object" << std::endl;
    }
};

答案 2 :(得分:1)

您应该至少在Prerequisites类中使用互斥锁和静态标志来再次保护先决条件对象的多次初始化。通过这种方式,您的代码将变为线程安全。