论C++构造函数中的不合理设计 (转)

2023-12-08 14:59

本文主要是介绍论C++构造函数中的不合理设计 (转),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

论C++构造函数中的不合理设计 (转)[@more@]论C++构造 函数中的不合理设计 作者:张岩 发布时间:2001/03/20   文章摘要:   在C++中,构造函数是一个在构建 对象的时候 调用的特殊的函数,其目的是对对象进行初始化的工作,从而使对象被使用之前可以处于一种合理的状态。但是,构造函数的设计并不完美,甚至有些不合理的特性。本文对这些问题进行了探讨,并提出了一些解决的方案。  
正文: Javascript:window.close()"> 1165976636218.GIF  



论C++构造函数中的不合理设计
  


  在C++中,构造函数是一个在构件对象的时候调用的特殊的函数,其目的是对对象进行初始化的工作,从而使对象被使用之前可以处于一种合理的状态。但是,构造函数的设计并不完美,甚至有些不合理的特性。比如说,限定构造函数名称与类的名称相同的条件。这些特性在构造C++编译器的时候是值得引起注意的。还有,在今后C++的标准修订或者制定其他面向对象的设计语言时候应当避免这些特性。这里也提出了一些解决的方案。
  C++中,任何类都有一个(至少有一个)构造函数,甚至在没有构造函数被声明的时候亦是如此。在对象被声明的时候,或者被动态生成的时候,这些构造函数就会被调用。构造函数做了许多不可见的工作,即使构造函数中没有任何代码,这些工作包括对对象的内存分配和通过赋值的方式对成员进行初始化。构造函数的名称必须与类的名称相同,但是可以有许多不同的重载版本来提供,通过参数类型来区分构造函数的版本。构造函数可以显式的通过用户代码来调用,或者当代码不存在是通过编译程序来隐式插入。当然,显式地通过代码调用是推荐的方法,因为隐式调用的效果可能不是我们所预料的,特别是在处理动态内存分配方面。代码通过参数来调用唯一的构造函数。构造函数没有返回值,尽管在函数体中可以又返回语句。每个构造函数可以以不同的方式来实例化一个对象,因为每个类都有构造函数,至少也是缺省构造函数,所以每个对象在使用之前都相应的使用构造函数。构造函数的调用如图1所示。

1165976636218.gif

图1. The activities involved in the execution of a constructor

  因为构造函数是一种函数,所以他的可见性无非是三种public、private、protected。通常,构造函数都被声明为public型。如果构造函数被声明为private或protected,就限制了对象的实例化。这在阻止类被其他人实例化的方面很有效。构造函数中可以有任何C++的语句,比如,一条打印语句,可以被加入到构造函数中来表明调用的位置。


构造函数的类型

  C++中构造函数有许多种类型,最常用的式缺省构造函数和拷贝构造函数,也存在一些不常用的构造函数。下面介绍了四种不同的构造函数。

1、缺省构造函数
  缺省构造函数是没有参数的函数。另外,缺省构造函数也可以在参数列表中以参数缺省值的方式声明。缺省构造函数的作用是把对象初始化为缺省的状态。如果在类中没有显式定义构造函数,那么编译器会自动的隐式创建一个,这个隐式创建的构造函数和一个空的构造函数很相像。他除了产生对象的实例以外什么工作都不做。在许多情况下,缺省构造函数都会被自动的调用,例如在一个对象被声明的时候,就会引起缺省构造函数的调用。

2、拷贝构造函数
  拷贝构造函数,经常被称作X(X&),是一种特殊的构造函数,他由编译器调用来完成一些基于同一类的其他对象的构件及初始化。它的唯一的一个参数(对象的引用)是不可变的(因为是const型的)。这个函数经常用在函数调用期间于用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。
  在C++中,下面三种对象需要拷贝的情况。因此,拷贝构造函数将会被调用。
  1). 一个对象以值传递的方式传入函数体
  2). 一个对象以值传递的方式从函数返回
  3). 一个对象需要通过另外一个对象进行初始化
  以上的情况需要拷贝构造函数的调用。如果在前两种情况不使用拷贝构造函数的时候,就会导致一个指针指向已经被删除的内存空间。对于第三种情况来说,初始化和赋值的不同含义是构造函数调用的原因。事实上,拷贝构造函数是由普通构造函数和赋值操作赋共同实现的。描述拷贝构造函数和赋值运算符的异同的参考资料有很多。
  拷贝构造函数不可以改变它所引用的对象,其原因如下:当一个对象以传递值的方式传一个函数的时候,拷贝构造函数自动的被调用来生成函数中的对象。如果一个对象是被传入自己的拷贝构造函数,它的拷贝构造函数将会被调用来拷贝这个对象这样复制才可以传入它自己的拷贝构造函数,这会导致无限循环。
  除了当对象传入函数的时候被隐式调用以外,拷贝构造函数在对象被函数返回的时候也同样的被调用。换句话说,你从函数返回得到的只是对象的一份拷贝。但是同样的,拷贝构造函数被正确的调用了,你不必担心。
  如果在类中没有显式的声明一个拷贝构造函数,那么,编译器会私下里为你制定一个函数来进行对象之间的位拷贝(bitwise copy)。这个隐含的拷贝构造函数简单的关联了所有的类成员。许多作者都会提及这个默认的拷贝构造函数。注意到这个隐式的拷贝构造函数和显式声明的拷贝构造函数的不同在于对于成员的关联方式。显式声明的拷贝构造函数关联的只是被实例化的类成员的缺省构造函数除非另外一个构造函数在类初始化或者在构造列表的时候被调用。
  拷贝构造函数是程序更加有效率,因为它不用再构造一个对象的时候改变构造函数的参数列表。设计拷贝构造函数是一个良好的风格,即使是编译系统提供的帮助你申请内存默认拷贝构造函数。事实上,默认拷贝构造函数可以应付许多情况。

3、用户定义的构造函数
  用户定义的构造函数允许对象在被定义的时候同时被初始化。这种构造函数可以有任何类型的参数。一个用户定义的和其它类型的构造函数在类 mystring 中得以体现:

  class mystring
  {......
  public: mystring(); // Default constructor
  mystring (mystring &src)
  // Copy constructor
  mystring (char * scr);
  // Coercion constructor
  mystring ( char scr[ ], size_t len);
  // User-Defined constructor

  }

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10790690/viewspace-961250/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10790690/viewspace-961250/

这篇关于论C++构造函数中的不合理设计 (转)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/470290

相关文章

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

Python中的可视化设计与UI界面实现

《Python中的可视化设计与UI界面实现》本文介绍了如何使用Python创建用户界面(UI),包括使用Tkinter、PyQt、Kivy等库进行基本窗口、动态图表和动画效果的实现,通过示例代码,展示... 目录从像素到界面:python带你玩转UI设计示例:使用Tkinter创建一个简单的窗口绘图魔法:用

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�