2.10 C++利用构造函数限制对象的创建

参考: http://www.weixueyuan.net/view/6342.html

总结:

  限制对象的创建。限制创建对象时能够按照我们需要的那样创建,而不能随意的创建对象。

  类中显示地声明了任意一个构造函数,系统均不会再自动生成构造函数。

  声明为private属性的构造函数,与声明为private属性的成员变量或普通成员函数一样,在类外同样是不能访问的 

在上一节构造函数的例1中,我们提到,如果不声明默认构造函数book(),而只声明带参构造函数book(char *a, double p)的时候,语句book Alice;是无法创建对象的。无法创建的原因在上一节已经讲明,这节就不再赘述了。

不过类的构造函数的这一特性却可以用来限制对象的创建。

[例1] 还是用 book 类来说明这节的内容:

  1. class book
  2. {
  3. public:
  4. void setprice(double a);
  5. double getprice();
  6. void settitle(char* a);
  7. char * gettitle();
  8. void display();
  9. private:
  10. double price;
  11. char * title;
  12. };

首先需要知道的是我们是在什么样的情况下才需要限制对象的创建。限制对象的创建不代表我们想禁止创建对象,只是加以限制而已,限制创建对象时能够按照我们需要的那样创建,而不能随意的创建对象。

比如例1中,我们定义了一个book类,声明对象的时候自然是为了描述某一本具体的书,这个时候如果我们直接采用book a;这样的方式创建一个对象a,编译当然是不会有问题的,毕竟系统会自动生成默认构造函数的。但是这样创建的对象a能代表什么呢?指的又是哪一本书?完全不清楚!

如果这个时候我们直接调用a.display()函数,那会发生什么就不好说了,毕竟a.price和a.title都没有初始化。这就是一个比较危险的程序了。不过肯定有人会说,不是可以通过a.setprice和a.settitle函数对两个成员变量进行赋值么?不错,确实可以这么做,但是万一给忘掉了呢?

对于这样的一个类,类的设计人员如果让book a;这样的创建对象的方式不成立,并且每次创建对象的时候就必须给书本的price和title赋值,这样问题不就解决了么?

这样的想法能实现么?回答是肯定的。我们可以通过构造函数来实现这一功能。看下面的几个类的示例。

[例2] 不声明默认构造函数:

  1. class book
  2. {
  3. public:
  4. book(char *a, double p);
  5. void setprice(double a);
  6. double getprice();
  7. void settitle(char* a);
  8. char * gettitle();
  9. void display();
  10. private:
  11. double price;
  12. char * title;
  13. };

[例3] 将默认构造函数声明为 private:

  1. class book
  2. {
  3. public:
  4. book(char *a, double p);
  5. void setprice(double a);
  6. double getprice();
  7. void settitle(char* a);
  8. char * gettitle();
  9. void display();
  10. private:
  11. book(){}
  12. double price;
  13. char * title;
  14. };

在例2中,我们在类中声明了一个带参构造函数book(char *a, double p);,如此一来默认构造函数就不会被系统自动生成了,也即不会生成book(){}这个构造函数,如此一来创建对象book a;则会出现编译错误,要想正确创建对象则必须进行初始化,如book Alice(“Alice in Wonderland”, 29.9);。

除了此种手段之外,例3的做法也是可行的,我们将默认构造函数主动声明并定义,最关键的是将其设置为private属性,也就是说无法在类外进行访问,如此一来book a;同样会报出编译错误,只不过这一次的错误是因为访问权限的问题,此时如果想要声明对象,则还是必须通过public属性的带参构造函数book(char *a, double p);来声明对象。

根据上面的几个例子,我们将系统不会自动生成默认构造函数的情况总结如下:

  • 类中显式地声明了默认构造函数,无论其属性被设置为public、private还是protected,系统都不会再自动生成默认构造函数了。
  • 类中显式地声明了其它任意一个不是默认构造函数的构造函数,系统均不会再自动生成默认构造函数。

其实这两点可以总结为一点,那就是当类中显示地声明了任意一个构造函数,系统均不会再自动生成构造函数。在例2中我们是采用第二种情况避免默认构造函数的产生,从而限制了类对象的随意创建。

在C++中之所以利用构造函数限制类对象的创建,意图已经很明显了,那就是要求程序设计人员在使用类创建对象的时候能够正确地进行初始化。

声明为private属性的构造函数,与声明为private属性的成员变量或普通成员函数一样,在类外同样是不能访问的,我们可以巧妙地使用这一点,限制类对象的随意创建。

时间: 08-30

2.10 C++利用构造函数限制对象的创建的相关文章

C#利用反射来判断对象是否包含某个属性的实现方法

本文实例展示了C#利用反射来判断对象是否包含某个属性的实现方法,对于C#程序设计人员来说有一定的学习借鉴价值. 具体实现代码如下: 1 /// <summary> 2 /// 利用反射来判断对象是否包含某个属性 3 /// </summary> 4 /// <param name="instance">object</param> 5 /// <param name="propertyName">需要判断的

Hibernate利用关联关系操纵对象

利用关联关系操纵对象 数据对象之间关联关系有一对一.一对多及多对多关联关系.在数据库操作中,数据对象之间的关联关系使用JDBC处理很困难.本节讲解如何在Hibernate中处理这些对象之间的关联关系.本节使用到4个类,它们分别是Student(学生).Card(学生证).Group(班级)和Course(课程),它们之间的关联关系如图1-1所示.这些实体存在级联(cascade)问题.例如,当删除一个班级的信息时,还要删除该班的所有学生的基本信息.如果直接使用JDBC执行这种级联操作,会非常烦琐

Java反射(三)在运行时利用反射分析对象

在运行时利用反射分析对象,其实就是利用反射来获得或者设置类的域.举例如下: 有一个Student类: package testreflection; public class Student { private String stuNum; public Student(String stuNum) { // TODO Auto-generated constructor stub this.stuNum = stuNum; } } 利用反射来获得和设置Student类的stuNum域的测试代码

利用构造函数 创建钟表

翻出来之前的一些效果,觉得这个时钟还挺好玩的就写出来共大家分享: HTML代码如下: <div id="box"> </div> 当前盒子用于插入钟表内容: js代码如下: <script> function clock(size,panBorderWidth){ this.size = size || 400; this.pan; this.panBorderWidth = panBorderWidth || 5; this.sp; this.mp

Javascript学习笔记:对象的创建

最基本的对象创建方式是通过Object构造函数或对象字面量的方式创建: ①通过Object构造函数的方式创建对象: 1 var person=new Object();//或者写成var person={} 2 person.name='张三'; ②通过对象字面量的方式创建对象: 1 var person={name:'张三'}; Object构造函数模式和对象字面量模式这两种创建对象的方式,都有明显的缺点:使用同一个接口创建很多对象的时候,会产生大量的重复代码.为解决这个问题,可以使用工厂模式

【JavaScript】【学习】对象的创建和继承

下午刚刚看完了<JavaScript高级程序设计>中的第六章,面向对象的程序设计,因为自己以前没有面向对象程序设计的基础,所以理解得有些困难,但是通过自己的努力研读+上网查资料+反复实践,总算是答题上理解了,对我的编程思维算是一个很大的提高吧,这里把学习笔记和心得发一下,方便以后自己查阅. 一.理解对象 在JavaScript中,一切皆是对象,前面学习引用类型,基本都是JavaScript中的内置对象,而基本类型,则都是这些内置对象的实例,BOM,DOM也是对象,全局变量可以视为window的

java类的初始化和对象的创建顺序

学习java编程思想--类的初始化p146 类的加载顺序* 1加载器启动找到 xxx.class文件,通过extends关键字寻找基类,先加载基类* 2类初始化先初始化static成员变量和static--->* 2先初始化父类的static成员变量和static* 3再初始化本类的static成员变量和static * 类加载之后,对象创建开始* 1先加载父类的非静态成员变量(静态成员变量在类初始化的时候已经加载,非静态成员变量要随对象的创建而初始化)* 2先加载父类的构造函数* 3再加载本类

Javascript我学之五对象的创建与使用

本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘. 对象的创建 JavaScript对象有两种类型 1).Native:在ECMAScript标准中定义和描述,包括JavaScript内置对象(数组,日期对象等)和用户自定义对象. 2).Host:在主机环境(如浏览器)中实现并提供给开发者使用,比如windows对象和所有的DOM对象 对象的含义 Object is an unordered collection of properties each of which contains

.NET对象的创建、垃圾回收、非托管资源的手动处理

本篇用来梳理对象的创建.垃圾的回收,以及非托管资源的手动处理. →首先运行应用程序,创建一个Windows进程. →CLR创建一块连续的虚拟地址空间,这个地址空间就是托管堆.而且,这个地址空间最初并没有对应的物理存储空间. 虚拟地址空间分成2段.一个区段是普通堆,也叫GC堆,大小小于85000字节的引用类型对象的实例被分配在这里:另一个是大对象堆,大小大于等于85000字节的引用类型对象的实例被分配在这里. 对于客户端应用程序,每个区段的大小大致是16MB:对于服务端应用程序,每个区段的大小大致

JavaScript 对象的创建

Object类型是JavaScript中使用最多的一种类型.创建Object实例的方式有多种,接下来一一列举. 1. Object构造函数 var person = new Object();person.name = "Brittany";person.age = 23;person.job = "web front-end engineer";person.sayName = function() {    console.log(this.name);};pe