【C/C++】构造函数被私有化,为什么还可以在类外直接new一个对象?

实例代码:

c 复制代码
// 饿汉模式 -> 定义类的时候创建单例对象
// 定义一个单例模式的任务队列
class TaskQueue
{
public:
    TaskQueue(const TaskQueue & t) = delete;
    TaskQueue& operator=(const TaskQueue& t) = delete;
    static TaskQueue* getInstance()
    {
        return m_taskQ;
    }

    void print()
    {
        cout << "我是单例对象的一个成员函数..." << endl;
    }

private:
    TaskQueue() = default;
    // TaskQueue(const TaskQueue& t) = default;
    // TaskQueue& operator=(const TaskQueue& t) = default;
    // 只能通过类名访问静态属性或方法
    static TaskQueue* m_taskQ;
};

TaskQueue* TaskQueue::m_taskQ = new TaskQueue;		// 加了类名作用域,实质仍在类内。

构造函数私有化(private),构造函数就不能通过外部访问,构造函数不能访问,自然就不能通过new创建一个新对象(new对象时,一定会初始化,即调用构造函数)。

那这里为什么还能 new TaskQueue 呢?还可以在类外直接new一个对象?

c 复制代码
TaskQueue* TaskQueue::m_taskQ = new TaskQueue;		// 返回new出来对象的地址

因为私有是相对作用域外,同一作用域没有这些概念,都是透明的。上面代码添加了类名作用域(TaskQueue::),表示这一句代码仍在类内,只不过是语法要求写在外面(在C++中,类的静态成员(static member)必须在类内声明,在类外初始化)。静态成员在外部初始化是语法要求,但初始化实质算在作用域内操作。

单例模式完整实例代码:

c 复制代码
#include<iostream>
using namespace std;


// 饿汉模式 -> 定义类的时候创建单例对象
// 定义一个单例模式的任务队列
class TaskQueue
{
public:
	TaskQueue(const TaskQueue & t) = delete;
	TaskQueue& operator=(const TaskQueue& t) = delete;
	static TaskQueue* getInstance()
	{
		return m_taskQ;
	}

	void print()
	{
		cout << "我是单例对象的一个成员函数..." << endl;
	}

private:
	TaskQueue() = default;
	// TaskQueue(const TaskQueue& t) = default;
	// TaskQueue& operator=(const TaskQueue& t) = default;
	// 只能通过类名访问静态属性或方法
	static TaskQueue* m_taskQ;
};

TaskQueue* TaskQueue::m_taskQ = new TaskQueue;		// 加了类名作用域,实质仍在类内。


int main()
{
	TaskQueue* m_taskQ = TaskQueue:: getInstance();
	m_taskQ->print();

	return 0;
}

m_taskQ 是私有的(private),类外不能访问,只能通过公用的成员函数(public)访问。能够操纵静态成员变量的函数,只有静态成员函数。

作用:在单例设计中,Singleton类在定义的时候将构造方法私有化,而在内部仅仅new出一个对象,是为了禁止别的类在外面直接new Singleton()出来,这样你只要在Singleton类中new一个对象,就能确保无论什么情况都只会产生一个Singleton对象,外部无法new出来,内部已经定义好了,有且仅有一个对象,这就是单列设计的核心。;单例设计模式目标是保证一个类在内存中对象的唯一性。所以要保证自己的类中创建了对象之后,其他的类不能再创建对象,只能获取这个对象。所以只要将本类中的构造函数私有化,其他程序就无法再创建该类对象。

相关推荐
qz5zwangzihan115 分钟前
题解:Atcoder Beginner Contest abc467 F - Email Scheduling Optimization
c++·贪心·atcoder·平衡树·abc467·abc467_f·fhq-treap
郝学胜-神的一滴1 小时前
中级OpenGL教程 023:Assimp模型加载全解——从源码到架构的骈文探秘
c++·unity·游戏引擎·cmake·unreal engine·opengl
星恒随风1 小时前
C++ STL 详解:list 的使用、迭代器失效、模拟实现与 vector 对比
开发语言·数据结构·c++·笔记·学习·list
牢姐与蒯1 小时前
c++之异常
开发语言·c++·c++11
此生决int1 小时前
深入理解C++系列(02)——类和对象(上)
开发语言·c++
zjun10013 小时前
C++:单例模式
c++·单例模式
同勉共进11 小时前
记一例 vibe coding + gcc bug 导致的线程池死锁问题
c++·线程池·gcc·死锁·vibe coding
我叫洋洋11 小时前
C ++ [ hello world ]
c语言·c++·算法
王维同学15 小时前
[自学][Windows C++]RunOnceEx 注册表分组键的安全遍历
c++·windows·安全·开源
Scott9999HH16 小时前
告别流量波动玄学!从法拉第电磁定律到底层 C/C++ 流量累积算法,深度解密工业级电磁流量计选型与开发
c语言·c++·算法