类静态变量私有化问题 您所在的位置:网站首页 私有静态变量初始化 类静态变量私有化问题

类静态变量私有化问题

2023-07-09 16:08| 来源: 网络整理| 查看: 265

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

懒汉模式

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; // 这是合法的,因为静态成员变量在类外部初始化

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

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

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

在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的构造函数是私有的,所以这是不允许的,会导致编译错误



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有