C++中构造函数或析构函数定义为private(转)
通常构造函数/析构函数的声明位于public区段,如果在private会有什么样的后果?
那么,private构造函数怎么才能被用到呢?两种方法:
1、使用友元类的对象中的方法来创建它。
2、在本类中实现static方法来创建它。
(1)构造函数定义private
在程序中实例化一个对象,编译器将调用构造函数。如果构造函数是private,由于在class外部不允许访问私有成员,将导致编译失败。
怎么解决这个问题呢?
对于类本身,可以利用static公有成员,因为它独立于class对象之外,不必构造对象就可以使用它们!在某个static函数中创建该class的对象,并以引用或指针的形式将其返回(不以对象返回,主要是构造函数是私有的,外部不能创建临时对象),就获得了这个对象的使用权。
问题:
static成员函数貌似不可以访问非static成员,为什么却可以访问私有的构造函数?
【实例】
class OnlyHeapClass
{
public:
static OnlyHeapClass* GetInstance()
{
// 创建一个OnlyHeapClass对象并返回其指针
return (new OnlyHeapClass);
}
void Destroy();
private:
OnlyHeapClass() {}
~OnlyHeapClass() {}
};
int main()
{
OnlyHeapClass *p = OnlyHeapClass::GetInstance();
... // 使用*p
delete p;
return 0;
}
// GetInstance()作为OnlyHeapClass的静态成员函数来在内存中创建对象:由于要跨函数传递并且不能使用值传递方式,所以选择在堆上创建对象,这样即使GetInstance()退出,对象也不会随之释放,可以手动释放。
// 构造函数私有化的类的设计保证了其他类不能从这个类派生或者创建类的实例。
还有这样的用途:
例如,实现这样一个class:它在内存中至多存在一个,或者指定数量个的对象(可以在class的私有域中添加一个static类型的计数器,它的初值置为0,然后在GetInstance()中作些限制:
每次调用它时先检查计数器的值是否已经达到对象个数的上限值,如果是则产生错误,否则才new出新的对象,同时将计数器的值增1。
最后,为了避免值复制时产生新的对象副本,除了将构造函数置为私有外,复制构造函数也要特别声明并置为私有。
如果将构造函数设计成Protected,也可以实现同样的目的,但是可以被继承。(当子类中的构造函数调用父类的private构造函数时会错,当子类中的构造函数调用父类中的 public或protected构造函数时是对的。)
(2)析构函数private
如何保证只能在堆上new一个新的类对象呢?只需把析构函数定义为私有成员。
原因:
C++是一个静态绑定的语言。在编译过程中,所有的非虚函数调用都必须分析完成。即使是虚函数,也需检查可访问性。因些,当在栈上生成对象时,对象会自动析构,也就说析构函数必须可以访问。
而堆上生成对象,由于析构时机由程序员控制,所以不一定需要析构函数。保证了不能在栈上生成对象后,需要证明能在堆上生成它。这里OnlyHeapClass与一般对象唯一的区别在于它的析构函数为私有。
那么如何释放它呢?答案也很简单,提供一个成员函数,完成delete操作。在成员函数中,析构函数是可以访问的。当然detele操作也是可以编译通过。
void OnlyHeapClass::Destroy() {
delete this;
}
构造函数私有化的类的设计可以保证只能用new命令在堆中来生成对象,只能动态的去创建对象,这样可以自由的控制对象的生命周期。但是,这样的类需要提供创建和撤销的公共接口。
转载:
http://www.blogjava.net/fhtdy2004/archive/2009/05/30/278971.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!