【问题标题】:How static function accessing private member function(constructor) of a class静态函数如何访问类的私有成员函数(构造函数)
【发布时间】:2017-04-04 22:37:15
【问题描述】:

我遇到了如下代码,这基本上是一个单例类的示例,我们将类构造函数设为私有,并提供一个静态公共函数来在需要时创建该类的实例。

我的问题是,当我们在静态函数内部调用new操作符创建单例类的对象时,肯定会调用该类的构造函数。我很困惑它是如何发生的,因为据我所知,静态函数只能访问类的静态成员和静态函数。那么它如何访问一个类的私有函数(构造函数)呢?

静态函数可以在不创建任何实例的情况下调用类的任何私有或公共成员函数吗?

#include <iostream>

using namespace std;

class Singleton
{
public:
    static Singleton *getInstance(); 

private:
    Singleton(){}
    static Singleton* instance;
};

Singleton* Singleton::instance = 0;
Singleton* Singleton::getInstance() 
{
    if(!instance) {
        instance = new Singleton(); //private ctor will be called
        cout << "getInstance(): First instance\n";
        return instance;
    }
    else {
        cout << "getInstance(): previous instance\n";
        return instance;
    }
}

int main()
{
    Singleton *s1 = Singleton::getInstance();
    Singleton *s2 = Singleton::getInstance();
    return 0;
}

但是当我编写如下示例代码时:

class Sample
{
    private:
        void testFunc()
        {
            std::cout << "Inside private function" <<std::endl;
        }
    public:
        static void statFunc()
        {
            std::cout << "Inside static function" <<std::endl;
            testFunc();
        }
};

int main()
{
    Sample::statFunc();

    return 0;
}

我在使用 g++ 时遇到编译错误:

file.cpp: In static member function ‘static void Sample::statFunc()’:
file.cpp:61: error: cannot call member function ‘void Sample::testFunc()’ without object. 

如果我们可以使用静态公共函数访问类的私有函数,那么为什么会出现此错误?

【问题讨论】:

  • 简短回答:恕我直言,是的。恕我直言,您的代码没有问题。 getInstanceSingleton 类的成员,因此它可以调用该类的所有方法,甚至是私有方法。

标签: c++ singleton private-members static-functions


【解决方案1】:

回答您稍后添加的问题的第二部分:

class Sample
{
private:
  void testFunc()
  {
    std::cout << "Inside private function" << std::endl;
  }
public:
  static void statFunc()
  {
    std::cout << "Inside static function" << std::endl;

    Sample s;
    s.testFunc();          // this is OK, there is an object (s) and we call 
                           // testFunc upon s

    // testFunc();         // this is not OK, there is no object
  }
  void InstanceFunction()
  {
    std::cout << "Inside public instance function" << std::endl;
    testFunc();
  }
};


int main()
{
  Sample s;
  s.InstanceFunction();

  Sample::statFunc();
  return 0;
}

无法从statFunc 内部调用testFunc();,因为testFunc(私有或非私有)是一个实例函数,您需要testFunc 可以操作的Sample 对象,但statFuncstatic 函数,因此没有 Sample 对象。

错误信息很清楚。

只有在提供对象的情况下,才能从statFunc 调用testFunc,参见上面的代码。

【讨论】:

  • 我认为单例类的构造函数也是类函数,不能被静态函数调用。如果构造函数可以在静态函数内部被调用,那么为什么不是普通的私有函数是什么让我困惑?
  • @Vikram 记住,构造函数不是普通的成员函数。当您编写instance = new Singleton(); 时,您正在创建一个对象,并在正在创建的对象上调用构造函数。
  • @Vikram,我已经编辑了答案,现在有一个示例,您可以从 statFunc 中调用 testFunc
【解决方案2】:

上述代码起作用的原因是getInstance()的实现调用了不需要对象实例的构造函数。

静态成员函数属于类而不是对象。因此,在调用静态成员函数时没有对象的实例,您无法访问 this 指针,因为没有一个。如果要从静态函数访问非静态私有成员函数,则需要将对象的引用传递给函数。例如

例如

class foo {
    public:
          foo(int i) : myInt(i) {}
          static int myStaticMethod(foo & obj);
    private:
          int myInt;
    };

    int foo::myStaticMethod(foo & obj) {
          return obj.myInt;
    }

#include <iostream>


int main() {
foo f(1);
std::cout << foo::myStaticMethod(f);
return 0;
};

【讨论】:

  • 感谢您的回答。所以我从上面了解到的是,由于 ctor 是一个特殊的成员函数,它不需要调用任何对象,因此可以使用静态函数(没有任何对象)调用它,但类的其他普通成员函数需要类实例为了调用它们,所以它们不能在没有对象的静态函数中被调用。
  • 是的,非常棒?
【解决方案3】:

静态函数可以在不创建任何实例的情况下调用类的任何私有或公共成员函数吗?

正在创建一个实例。

instance = new Singleton();

new 关键字创建一个Singleton 对象。

而且,是的,因为Singleton::getInstance 是该类的成员函数,所以它能够调用构造函数(尽管请注意您只是间接地这样做),无论它是否是static

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多