【问题标题】:Can constructor be called from static functions?可以从静态函数中调用构造函数吗?
【发布时间】:2011-05-02 08:32:22
【问题描述】:

如果之前有人问过这个问题,我很抱歉(我试图找到它但徒劳无功)。 我在http://sourcemaking.com/design_patterns/singleton/cpp/1 经历了单例设计模式(代码从那里复制)

class GlobalClass
{
    int m_value;
    static GlobalClass *s_instance;
    GlobalClass(int v = 0)
    {
        m_value = v;
    }
  public:
    int get_value()
    {
        return m_value;
    }
    void set_value(int v)
    {
        m_value = v;
    }
    static GlobalClass *instance()
    {
        if (!s_instance)
          s_instance = new GlobalClass;
        return s_instance;
    }
};

// Allocating and initializing GlobalClass's
// static data member.  The pointer is being
// allocated - not the object inself.
GlobalClass *GlobalClass::s_instance = 0;

void foo(void)
{
  GlobalClass::instance()->set_value(1);
  cout << "foo: global_ptr is " << GlobalClass::instance()->get_value() << '\n';
}

void bar(void)
{
  GlobalClass::instance()->set_value(2);
  cout << "bar: global_ptr is " << GlobalClass::instance()->get_value() << '\n';
}

int main()
{
  cout << "main: global_ptr is " << GlobalClass::instance()->get_value() << '\n';
  foo();
  bar();
}

我的问题是 如果(!s_instance) s_instance = new GlobalClass;

s_instance = new GlobalClass 将调用构造函数,但构造函数是非静态的,我们从静态函数调用它。这是如何运作的?构造函数在这方面“特殊”吗?

谢谢!

【问题讨论】:

  • 唯一不能做的就是从同一个类的静态方法内部调用一个类方法。这很明显,因为方法需要一个可以调用的对象,而静态方法则不需要。
  • 请注意,如今单身人士非常不受欢迎。观看this video 了解原因。总结:单例是全局变量,全局变量引入隐式依赖,隐式依赖是测试、调试和维护的噩梦。
  • 请记住,每个程序都从 main 函数开始,而 main 是一个静态函数。所以是的,你可以。
  • 如果你打算使用单例(你可能不应该这样做)那么请不要那样实现它。指针是可怕的,如果你不需要,就不应该使用(而且你不在这里(如果事实指针使单点更难正确执行)。问自己这个问题单点将如何/何时被销毁?

标签: c++ static constructor


【解决方案1】:

您可以从任何地方调用构造函数。如果你不能在没有实例的情况下调用构造函数,你首先如何获得任何实例?

您可能已经无数次地从普通函数中调用它们。静态函数也不例外。

【讨论】:

    【解决方案2】:

    是的,可以从静态函数调用构造函数。每当创建新对象时,编译器都会自动调用构造函数。它有助于正确初始化类成员。是的,在某种程度上,您可以将 Constructor 视为可以从静态函数调用的特殊函数。

    在上面的代码中,您正在实现一种称为Singleton 的设计模式。

    【讨论】:

    • 感谢您的快速回复。我想了解更多关于它的信息。我在哪里可以找到更多信息?例如是否在标准中定义(如果是,在哪里)。你有一些方便的链接让我深入研究吗?一些值得信赖的来源会很好:) 再次感谢。
    • @Anon:这不是 C++ 标准。您只是在静态函数中创建一个新对象,这与从 main() 或任何其他静态函数创建对象没有什么不同。为了简单起见,我这么说。您只需要记住,每当创建对象时都会调用构造函数(与创建对象的位置无关)
    【解决方案3】:

    第 1 点:在 C++ 中,不能在静态成员函数中调用非静态成员函数。原因是静态函数中没有“this”指针构造函数也不例外

    class A
    {
    public:
        void fun(){};
        static void static_fun()
        {
            // This is illegal because fun() is non-static
            fun();
        }
    };
    

    第 2 点:您始终可以调用不同对象的方法,即使它是非静态的

    class A
    {
    public:
        void fun(){};
        static void static_fun(A& a)
        {
            // Legal here because it's a (different) object..
            a.fun();
        }
    };
    

    结论

    它与代码中的构造函数无关。因为您正在创建另一个对象。你可以调用它的所有公共方法,包括它的构造函数。

    【讨论】:

    • OP 肯定非常了解这一点,因此他/她对构造函数有疑问。仔细阅读 Q。
    • @Als,请再次阅读我的回答。我认为 OP 可能会与它混淆。
    • 啊抱歉..我在您编辑的答案之前添加了评论。
    【解决方案4】:

    是的,

    • 很简单:使用new ClassName --> 它将调用构造函数(在新实例上...)
    • 非常重要:placement new(仅对非常明确的库实现类型、场景有用)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 2010-09-23
      • 2014-09-02
      • 2011-05-08
      • 1970-01-01
      • 2011-02-24
      相关资源
      最近更新 更多