private与构造函数

2023-05-16

通常我们都将构造函数的声明置于public区段,假如我们将其放入private区段中会发生什么样的后果?没错,我也知道这将会使构造函数成为私有的,这意味着什么?

    我们知道,当我们在程序中声明一个对象时,编译器为调用构造函数(如果有的话),而这个调用将通常是外部的,也就是说它不属于class对象本身的调用,假如构造函数是私有的,由于在class外部不允许访问私有成员,所以这将导致编译出错。

    你于是说:“哈哈。”我们制造了一个似乎无法产生对象的class.哦,当然,对于class本身,我们还可以利用它的static公有成员,因为它们独立于class对象之外,我们不必产生对象也可以使用它们。嗯,看来我们还是为带有私有构造函数的类找到了一个存在的理由。不过我们不应当满足于此,因为看上去应当还有发掘的余地。

    首先我们来认真看一下是不是真的无法创建出一个具有私有构造函数的类对象。“呃,可能未必。”你现在也许会这样说。这很好,让我们再来看看为什么,没错,因为构造函数被class私有化了,所以我们要创建出对象,就必须能够访问到class的私有域;但这一点“我们”是做不到的,那么,谁能做得到呢?class的成员可以做得到;但在我们建构出其对象之前,怎么能利用它的成员呢?噢,刚才我们刚刚提到了static公有成员,它是独立于class对象而存在的,当然,它也是公有的,“我们”可以访问得到。假如在某个static函数中创建了该class的对象,并以引用或者指针的形式将其返回(不可以以值的形式返回,想想为什么),我们就获得了这个对象的使用权。下面是例子:
 

class WonderfulClass
{
public:
    static WonderfulClass* makeAnObject()
    {
        // 创建一个WonderfulClass对象并返回其指针
        return (new WonderfulClass);
    }
private:
    WonderfulClass() { }
};

int main()
{
    WonderfulClass *p = WonderfulClass::makeAnObject();

    ... // 使用*p

    delete p;  // Not neccesary here, but it's a good habit.

    return 0;
}


   嗯,这个例子使用了私有构造函数,但它运行得很好:makeAnObject()作为WonderfulClass的静态成员函数,尽心尽责地为我们创建对象:由于要跨函数传递并且不能使用值传递方式,所以我们选择在堆上创建对象,这样即使makeAnObject()退出,对象也不会随之蒸发掉,当然,使用完之后你可不要忘了手工将它清除。

    回到前面的思路:除了公有的static成员可以帮助我们访问私有域外,还有没有其它可以利用的“东西”?

    噢,你一定想到了使用友元,完全正确。可以使用该类的友元函数或者友元类创建其对象,这里就不举例了。

    我们知道没有人会无聊到无缘无故把一个class设为私有,然后再写一个和上面一模一样的makeAnObject()来让它的用户体验一下奇特的感觉。我们也不太相信这只是由于C++的设计原因而导致的一个“顺便的”“特殊的”“无用的”边角功能。它应当是有实际用途的。提醒一下,到了JAVA中你会更容易明白很多静态方法创建对象的原理!!!

    嗯,例如,我们想实现这样一个class:它至多只能存在一个,或者指定数量个的对象(还记得标准输入输出流库中那个独一无二的cout吗?),我们可以在class的私有域中添加一个static类型的计数器,它的初值置为0,然后再对makeAnObject()做点手脚:每次调用它时先检查计数器的值是否已经达到对象个数的上限值,如果是则产生错误,否则才new出新的对象,同时将计数器的值增1.最后,为了避免值复制时产生新的对象副本,除了将构造函数置为私有外,复制构造函数也要特别声明并置为私有。
 

后记:
上面的仁兄评论堪称经典,总结一下就是为了避免创建对象时调用类的构造函数,而是想将生成对象的方式以其它的方式实现,则可将所有的构造函数声明为非public的,这样并不意味着该类无意义,不能实例化生成对象。
生成对象可以两种方式:
1. 通过同时为该类声明Public的static成员函数,在该static成员函数中调用该类私有的构造函数,生成实例,static成员函数是属于任何一个对象,而是属于类的,故可以在没有该类的对象的情况下,通过<类名>::<static 公有成员函数名>(参数)的方式来实现。
2. 调用该类的私有构造函数并生成类对象实例还可以通过该类的友元函数,或该类的友元类的成员函数调用此私有构造函数来实现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

private与构造函数 的相关文章

  • C# 像 C++ 一样将所有内容设为公共/私有? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我最近开始学习 C 但我有一些 C 背景 我想知道我会怎么做类似的事情 class em
  • 将析构函数设置为私有有什么用?

    将析构函数设置为私有有什么用 基本上 任何时候您希望其他类负责您的类对象的生命周期 或者您有理由阻止对象的销毁 您都可以将析构函数设为私有 例如 如果您正在执行某种引用计数操作 则可以让对象 或已成为 好友 的管理器 负责计算对其自身的引用
  • 没有办法在 JavaScript 中拥有基于类的对象吗?

    基于 javascript 原型的面向对象编程风格很有趣 但是在很多情况下您需要能够从类创建对象 例如 在矢量绘图应用程序中 工作区在绘图开始时通常是空的 我无法从现有的 线 创建新的 线 更一般地说 动态创建对象的每种情况都需要使用类 我
  • Rust impl 具有私有字段的默认特征

    当我进行此类设置时 我收到错误 默认 测试 rs mod default mod use default mod Point fn main let p1 Point new let p2 Point Point z 1 Default d
  • C++ - 构造函数重载 - 私有和公共

    你能告诉我为什么下面的代码给我以下错误 重载 C int 的调用不明确 我认为由于 C char x 是私有的 因此只有 C float ctor 从外部可见 并且应该通过将 int 转换为 float 来调用它 但事实并非如此 class
  • C++:重写公共\私有继承

    If B继承自A using public can B覆盖其中一个函数并强制其为私有 class A public virtual double my func1 int i virtual double my func2 int i cl
  • TypeScript 中的 private 关键字和私有字段有什么区别?

    在 TypeScript 3 8 中 使用private将成员标记为私有的关键字 class PrivateKeywordClass private value 1 并使用 私人领域建议用于 JavaScript https github
  • 当类型信息不可用时如何转换为私有内部类?

    我有类似以下情况 In some library code public class A private class B Object value In my code Object o o is initialized to an ins
  • 在嵌套匿名结构上忽略 C++ 私有修饰符

    以下示例代码在 Visual C 中编译得很好 class Test private struct struct int privateData int main int char Test test test privateData 0
  • JUnit 测试私有变量? [复制]

    这个问题在这里已经有答案了 我被分配了对一个我从未直接使用 JUnit 进行过工作的类进行单元测试的任务 并且严格禁止更改包中的代码 这通常不是问题 因为我们的大多数单元测试只是为了功能和输入 输出一致性 这可以简单地通过运行例程并检查其返
  • Java反射带参数的私有方法最好的方法是什么?

    我正在尝试使用java反射调用私有方法我开发了一个小方法来调用其他方法迭代所有方法并按名称和参数类型进行比较我已成功调用4个方法 我有一个问题 1 这是最好的方法吗 因为我知道 class getMethod 仅匹配公共方法 Java有内置
  • 私有内部类综合了意想不到的匿名类

    当您编译带有私有 内部类的 Java 类时 由于某种原因 似乎会自动合成一个匿名类 这个类足以重现它 public class SynthesizeAnonymous public static void method new InnerC
  • ES6代理类,访问私有属性(无法从类未声明的对象中读取私有成员#hidden)

    我正在研究代理对象 类和私有属性 并遇到了这个错误消息 home marc projects playground pipeline clsss js 14 this hidden this hidden TypeError Cannot
  • 我可以转换对象并访问 C++ 中的私有数据成员吗?

    我想访问类中的私有数据成员 类中没有成员函数来访问私有数据成员 这是私人的 我想上这门课 想知道如何打开它 一种方法是复制类的声明 将私有成员设为公共 然后将新类称为 some else 然后我重新解释转换并复制原始对象 这有效 但我想要一
  • 为什么建议将实例变量声明为私有?

    我的问题与Java有关 但它也可以应用于C 我想知道为什么每个人都建议创建实例变量private而不是制作它们受保护的 我们想一想 子类看不到私有变量 因此如果我需要访问或更改子类中超类的变量 我被迫使用一些访问器和修改器方法 例如getM
  • 子类需要访问抽象超类的私有属性

    我有一个抽象 java 类 它实现了它的几个方法 但没有实现其他方法 在它实现的方法中 它使用私有属性变量 使用的变量也需要在子类中使用 据我所知 我的选择是 在子类和超类中都声明私有变量 将抽象类中当前实现的方法的实现推迟到子类中 还有其
  • NSTokenField 捕获一些 NSEvents

    我需要为 NSTokenField 和解决方案实现 Command Enter Command O 和 Esc 快捷键https stackoverflow com a 18486965 1067147 https stackoverflo
  • 从类定义中省略“private”关键字是否会造成混淆?

    我最近删除了一个private从类定义中指定 因为它位于顶部 紧接在class关键词 class MyClass private int someVariable 我认为这是多余的 一位同事不同意这一点 称这实际上 隐藏 了private数
  • C# 中的私有“集合” - 无法理解它

    我见过很多使用类似的东西编写的示例代码 请原谅这是多么可怕的罐头 public class Test public object Thingy get private set 不幸的是 这些例子从未真正解释为什么 set 被设置为私有 所以
  • 私有方法真的安全吗?

    在Java中private访问修饰符被认为是安全的 因为它在类外部不可见 那么外界也不知道这个方法 但我认为Java反射可以用来打破这个规则 考虑以下情况 public class ProtectedPrivacy private Stri

随机推荐

  • 让人“眼前一亮、不明觉厉”的互联网技术PPT

    目录 1 互联网 1 1 智能 43 1 2 云计算 1 3 5G 2 大数据 2 1 用户画像 2 2 边缘计算 2 3 工业大数据 2 4 医疗大数据 2 5 数据平台 2 6 银行大数据 3 物联网 3 1 物联网产业 3 2 工业物
  • 基于FPGA的电梯控制系统设计

    在本项目中一共分为了五个模块 xff1a 时钟分频 按键消抖 状态控制 蜂鸣 译码显示及流水指示灯 其模块的作用分别是 xff1a 时钟分频 xff1a 将高频率系统时钟通过分频得到不同合适频率的时钟频率作为不同模块的输入时钟 clk xf
  • 【流媒体视频监控平台开发wvp-GB28181-pro】

    wvp GB28181 pro学习心得 wvp与GB28181介绍1 流媒体服务器视频协议介绍2 市面上的流媒体服务器3 wvp GB28181 pro框架需要学习的框架和工具4 工具准备项目整合和配置 wvp与GB28181介绍 学习原因
  • gazebo创建机器人模型06

    gazebo创建机器人模型05 kinect 信息仿真以及显示 kinect摄像头仿真基本流程 xff1a 1 已经创建完毕的机器人模型 xff0c 编写一个单独的 xacro 文件 xff0c 为机器人模型添加 kinect 摄像头配置
  • 【C++】C++中防止头文件重复包含的两种方法

    文章目录 01 错误分析 xff1a 类型重定义 xff08 头文件重复包含 xff09 02 解决方案2 1 微软宏2 2 条件编译2 3 两种方法比较 03 变量被重复包含3 1 解决办法 04 版权声明 amp 总结 01 错误分析
  • C/C++程序员应聘常见面试题深入剖析

    1 引言 本文的写作目的并不在于提供C C 43 43 程序员求职面试指导 xff0c 而旨在从技术上分析面试题的内涵 文中的大多数面试题来自各大论坛 xff0c 部分试题解答也参考了网友的意见 许多面试题看似简单 xff0c 却需要深厚的
  • Nvidia jetson tx2 详细安装、配置教程以及固定ip

    jetson tx2 是什么 一 硬件组装 xff1a 1 将 Wi Fi 天线插上 xff0c 组装好充电器即可 2 接口介绍 xff1a USB接口只有一个 xff08 建议使用USB拓展 xff0c 方便前期配置的时候连接键盘鼠标 x
  • C语言 用指针实现字符串函数 strlen strcpy strcat strcmp

    目录 一 指针模拟实现strlen 函数 1 strlen 函数description 2 用指针实现且将strlen封装 3 运行结果 二 指针模拟实现strcpy 函数 1 strcpy 函数description 2 用指针实现且将s
  • 常用器件介绍

    常用器件介绍 这篇文章主要介绍一些在做电子设计时最最常见的器件 xff0c 针对的是完全的小白们 面包板 首先是搭建设计电路用的面包板 面包板正面图 背面拆解图 面包板是专为电子电路的无焊接实验设计制造的 xff0c 上面有很多小插孔 各种
  • VScode代码格式化解决方案c/c++

    前贴链接 xff1a https tieba baidu com p 7891213649 之前说过研究出来了会和大家分享一下自己是如何解决的 xff0c 于是就有了此贴 首先要说明 xff0c 本文主要是针对c c 43 43 xff0c
  • C语言输入和输出

    文章目录 一 数据输入二 数据输出三 断章取义四 printf输出1 输出描述性的文字2 输出整数3 输出字符4 输出浮点数5 输出字符串6 输出多个内容7 示例 xff08 book12 c xff09 五 scanf输入1 输入整数2
  • c 和 python语法 对比

    直接干货 xff1a 先稍微了解两种语言的基本不同 pythonc执行方式无需手动编译 xff0c 执行时按行读取 xff0c 自动编译成字节码 所以python可轻易被获取源码需要手动进行编译生成机器可直接执行的机器码内存管理有自己的垃圾
  • 删除typora图片目录下失效的图片脚本

    背景 xff1a md中插入图片与word不同 xff0c 在word中图片是拷贝了一份放在文件中 xff0c 与原图片无关 xff0c 所以无论删除哪个互不影响 xff0c 但是md中却不同 xff0c md中插入图片时用超链接的方式从外
  • scanf中‘\n‘的用法和隐患

    读到这篇文章的人90 的可能是遇到了输入字符后 xff0c 回车没有预期的输出 xff0c 连续回车都没用 这种情况可能是因为你在scanf中加了 n xff0c 而且加了不该加的地方 把代码里的 n删了或者再输入一个不是 n的字符再回车
  • c语言使用一维数组实现杨辉三角

    通常使用在实现杨辉三角时使用的时使用二维数组的方式 xff0c 这种方式比较快捷 xff0c 且比较好理解 xff0c 但是使用二维数组浪费了大量的空间 xff0c 又大概一般的空间未被使用 如果使用一维数组进行计算能大大提高空间利用率 首
  • 链表、结构体和数组对比

    结构体和数组 1 结构体可以存不同类型的元素 而数组只能存同一类型 2 结构体类型需要我们自已定义 数组是用别的类型加 元素个数 3 结构体内存分配方式很特别 使用对齐原则 不一定是所有元素的字节数和 而数组一定是所有元素的字节数和 4 结
  • C和C++那些事儿

    1 new delete malloc free关系 delete会调用对象的析构函数 和new对应free只会释放内存 xff0c new调用构造函数 malloc与free是C 43 43 C语言的标准库函数 xff0c new del
  • 排序和复杂度

    常见的排序方式 1 冒泡排序 xff1a 时间复杂度 xff1a 最好情况是 O n xff0c 最坏情况是 O n2 空间复杂度 xff1a 开辟一个空间交换顺序O 1 2 快速排序 xff1a 时间复杂的 xff1a 最好情况是 O n
  • 文件IO过程

    基本概念 xff1a 文件描述符 xff1a xff08 文件描述符有时称为文件句柄 xff09 进程级 xff09 文件描述符是一个简单的整数 xff0c 用以标明每一个 被 进程所打开的文件和socket 通常0 1 2被标准输入 标准
  • private与构造函数

    通常我们都将构造函数的声明置于public区段 xff0c 假如我们将其放入private区段中会发生什么样的后果 xff1f 没错 xff0c 我也知道这将会使构造函数成为私有的 xff0c 这意味着什么 xff1f 我们知道 xff0c