1

我使用一个全局变量(一个类的对象)并将其定义如下:

//foo.h
extern class_name obj_name;
//foo.cpp
class_name obj_name("directory of a .ttf file");

我将 foo.h 包含在我的 main.cpp 中,我的 main() 函数所在的位置。

问题是我不太喜欢在那里初始化它,因为它不在函数内部。它是公开的。我宁愿调用一个初始化对象的“init()”函数,如:

object_name = class_name(parameters);

来自 main() 函数。

但是该类是第 3 方的,它不接受在没有我们为构造函数提供参数的情况下创建的对象。也许它没有默认的无参数构造函数。

做我上面做的事情是好的编码风格吗?

4

5 回答 5

3

Construct on first use idiom可以为您省去一些后顾之忧:

// foo.h

class_name& get_obj();

// foo.cpp

class_name& get_obj()
{
    static class_name obj("dir");
    return obj;
}

另一个链接。

于 2012-07-03T09:51:35.440 回答
3

不。

不要在没有充分理由的情况下在 C++ 中使用全局变量。

  • 您将遇到“静态初始化顺序惨败”。
  • 你会得到难看的意大利面条代码。
  • 您的代码将难以测试。

如果您的全局是第 3 方类型,则尤其如此。

考虑使用更好的东西,比如允许延迟初始化的工厂方法。或者只是将对象传递给需要它的函数。

还可以考虑用您自己的包装该第 3 方类 - 仅提供测试它所需的最小接口,并使用指向该抽象基类的指针。(或者如果 3rd 方库支持它 - 使用他们提供的最小接口,您可以使用它)

于 2012-07-03T09:41:37.167 回答
1

全局变量几乎总是不好的。但是,如果您没有其他选择(是吗?)我会建议使用指针。这样你就可以在任何你想要的地方定义全局指针,并在 main 或任何其他使用 operator new 的函数中初始化它。但是,这使您负责手动删除对象。

于 2012-07-03T09:43:05.860 回答
0

当然,这不是一种好的编码风格。但并非所有 3ed 派对 API 都是以“正确的方式”创建的,因此在某些情况下您会违反规则。如果你这样做了,你至少可以严格地评论它,这样你将来就会知道你为什么这样做。

于 2012-07-03T09:44:40.697 回答
0

也许这样的事情可以帮助:

class ObjectFactory 
{
public:
    static class_name* getObject() 
    {
        if( ptr ) 
            return ptr;
        else
        {
            ptr = new class_name( <args> );
            return ptr;
        }                
    }

private:
    static class_name* ptr;

    ObjectFactory() : ptr(NULL) {}
}

每次您需要使用该对象时,您总是可以这样做:

class_name *p = ObjectFactory::getObject();
于 2012-07-03T09:56:11.980 回答