2010-05-29 27 views
3

我想做什么:每当该类的实例将在程序中使用时,运行一些必备代码。这段代码将检查requiremts等,并且应该只运行一次。构造函数中的静态变量,是否有任何缺点或副作用?

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

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; 
     } 
}; 

让我困扰的是,我还没有看到类似用途的静态变量至今。是否有任何缺点或副作用或我错过了什么?或者也许有更好的解决方案?欢迎任何建议。

+0

我认为你应该重新考虑你的设计,而不是将任何prereq作为参数传递给构造函数。它使你的类的用户更加清楚依赖。 – 2010-05-29 23:22:47

+0

@Anders K:这不是关于类用户的选择,而是关于测试运行时环境。更具体地说,我想要例如检查C类将使用的可用OpenGL扩展。无论何时需要的扩展程序不可用,程序都会打印出错信息并退出。 – doc 2010-05-29 23:31:19

+0

我的意思是使用你的课程的用户(程序员)。更清楚的是,构造函数是否需要知道可用的opengl扩展,然后在幕后静静地进行。 – 2010-05-29 23:37:39

回答

5

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

如果你没有问题,你可以这样做,虽然游戏范围的构造函数系统没有可发现性(例如,一旦你忘记了'技巧'或其他人试图读你的代码,他们会很困惑到发生了什么)。

+0

感谢您的建议。线程安全目前不是问题。 – doc 2010-05-29 23:24:31

+0

@doc在这里稍后,但以至少_thread conscious_(而不是明显的线程无关紧要)的方式编写代码通常会产生更清晰,更快,更好,更具弹性的代码。 – Qix 2016-12-14 10:43:17

+0

@Qix“线程意识”是什么意思? – doc 2016-12-14 21:33:46

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; 
    } 
}; 
+0

你可能是对的,这更清楚。但是在checkOnce()中将'checkedOnce'布尔值定义为static是怎么回事?不太详细,仍然应该清楚(?)。 + C++ 0x中的原子性。 – doc 2010-06-04 21:27:59

+0

@doc - 我提出这个更详细的方式,因为它更清晰/更明确/使用更少的魔法。你能提供关于C++ 0x中静态局部变量原子性的引用/引用吗? – ChrisW 2010-06-04 22:21:52

+0

我读到这里在以下链接下stackoverflow http://stackoverflow.com/questions/898432/how-is-static-variable-initialization-implemented-by-the-compiler/898603#898603 – doc 2010-06-05 00:24:58

1

您应该至少在Prerequisites类中使用互斥体和静态标志来保护先决条件对象的多重初始化。这样你的代码就会变成线程安全的。

+0

线程安全不是一个问题在这里,但感谢您的建议。顺便说一句我听说C++ 0x将使静态变量的线程安全初始化。 – doc 2010-05-30 00:13:15

相关问题