类静态变量私有化问题

今天在看两种单例模式的时候有一点疑惑查了点资料,记录一下

懒汉模式

class Singleton
{
private:
	static Singleton* instance;
private:
	Singleton() {}
	Singleton(const Singleton&);	//这是一个函数声明,函数定义的时候需要给具体参数名
public:
	static Singleton* getInstance()
	{
		if (instance == nullptr)
			instance = new Singleton();
		return instance;
	}
};
Singleton* Singleton::instance = nullptr;

饿汉模式

class Singleton
{
public:
	static Singleton* getInstance()
	{
		return instance_;
	}
private:
	Singleton() {}
	Singleton(const Singleton&);
	static Singleton* instance_;
};
Singleton* Singleton::instance_ = new Singleton();

在看这个单例模式的时候出现了一个问题

静态私有成员变量是否受到private的私有限制

先说结果:受到private的限制,即使是static加上私有限制也不能从类外访问

在C++中,静态成员变量是属于类的,而不是属于类的任何特定对象的。这意味着,无论你创建了多少个类的对象,静态成员变量只有一个副本。静态成员变量在所有对象之间共享,它们在类外部初始化。

私有静态成员变量的初始化是一个特例。尽管它们是私有的,但是它们可以在类外部初始化。这是因为静态成员变量的初始化不是通过访问控制进行的,而是在编译时进行的。在编译时,编译器知道静态成员变量的类型和大小,因此可以为它们分配内存和初始化。

class MyClass {
private:
    static int myPrivateStaticVar;

public:
    void myFunction() {
        myPrivateStaticVar = 10;  // 这是合法的,因为myFunction是MyClass的成员函数
    }
};

int MyClass::myPrivateStaticVar = 0;  // 这是合法的,因为静态成员变量在类外部初始化

在这个例子中,myPrivateStaticVarMyClass的私有静态成员变量。尽管它是私有的,但是它可以在类外部初始化。这是因为静态成员变量的初始化在编译时进行,而不是在运行时进行。

然而,尽管你可以在类外部初始化私有静态成员变量,但是你不能在类外部访问它。如果你试图在类外部访问私有静态成员变量,编译器将会报错。

在全局使用作用域的时候编辑器提示可以使用私有变量的问题

在C++中,私有成员(包括变量和函数)只能在类的内部访问,这是封装的一个重要方面。私有成员的访问权限是受限的,只有类的成员函数和友元函数可以访问。

当你在全局范围内使用类的作用域时,编辑器可能会提示你可以使用私有变量,这是因为编辑器在提供代码提示时,会考虑到所有可能的代码片段,包括私有成员。然而,这并不意味着你可以在全局范围内访问私有成员。如果你尝试这样做,编译器将会报错。

int Singleton::a = 1;	//编辑器报错,非静态数据成员不能在类外定义

当你在函数内部使用类的作用域时,你已经离开了类的作用域,进入了函数的作用域。在函数的作用域内,你不能访问类的私有成员,包括私有变量。因此,编辑器在提供代码提示时,不会提示私有变量。

class MyClass {
private:
    int myPrivateVar;
};

void myFunction() {
    int var = MyClass::myPrivateVar;  // 这将导致编译错误,因为myPrivateVar是私有的
}

为什么调用私有构造函数没有报错

代码是上述单例模式饿汉模式中的

Singleton* Singleton::instance_ = new Singleton();
Singleton* a = new Singleton();

上述两端代码第一个编辑器不报错,第二个编辑器报错

Singleton* Singleton::instance_ = new Singleton();

这行代码是在类的内部初始化静态成员变量instance_。尽管构造函数是私有的,但是类的静态成员可以访问类的所有成员,包括私有成员。因此,这行代码是合法的,不会导致编译错误。

Singleton* a = new Singleton();

这行代码试图在类的外部创建一个新的Singleton实例。因为Singleton的构造函数是私有的,所以这是不允许的,会导致编译错误

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值