我遇到了类似下面的代码,它基本上是一个单例类的例子,我们将类构造函数设置为private,并提供一个静态公共函数来在需要时创建类的实例 .
我的问题是当我们调用 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.
如果我们可以使用静态公共函数访问类的私有函数,那么为什么我会收到此错误?
3 回答
上面代码工作的原因是因为
getInstance()
的实现调用了不需要对象实例的构造函数 .静态成员函数属于类而不是对象 . 因此在调用静态成员函数时没有对象的实例,你不能访问
this
指针,因为没有一个 . 如果要从静态函数访问非静态私有成员函数,则需要将对象的引用传递给函数 . 例如例如
您正在创建一个实例 .
new
关键字创建Singleton
对象 .并且,是的,因为
Singleton::getInstance
是该类的成员函数,它具有调用构造函数的能力(尽管请注意're doing so only indirectly), whether it' sstatic
.回答您稍后添加的问题的第二部分:
无法从
statFunc
内部调用testFunc();
,因为testFunc
(私有或非私有)是实例函数,您需要testFunc
对象testFunc
可以操作,但statFunc
是static
函数,因此没有Sample
对象 .错误信息非常清楚 .
只有在提供对象时才可以从
statFunc
调用testFunc
,请参阅上面的代码 .