c++总结之类型,对象的定义和声明,对象的初始化和赋值

一、对象的类型

对象的类型决定了对象占用内存空间的大小,和内存的布局,内存中可存储值的范围以及对该对象可以进行的操作,由于对象的类型决定可以对其执行的操作,因此const属性也可以看做对象类型的组成部分。类型又分为静态类型和动态类型,对于普通对象,静态类型和动态类型一般是一致的;对于指针和引用类型,静态类型和动态类型可以相同也可以不同,静态类型是指针和引用定义时声明的类型,而动态类型是指程序运行时实际绑定的类型。当静态类型和动态类型不同时,一般来说有两种情况:一是指涉到常量的指针和引用绑定了一个变量,主要用于对数据的写保护;二是直指涉到子孙类的对象,C++通过这种机制实现面向对象中的多态。在后一种情况下,超类在子类中的内嵌对象被继承访问修饰符允许访问其public成员时才可以进行绑定,即public继承自父类的子类任何时候都可以绑定到父类的指针和引用(继承访问修饰符使得父类的public成员永远可见),protected继承自父类的子类在其本身作用域,其本身的子类,其友元内可以绑定到父类的指针和引用(继承访问修饰符使得父类的public成员变成它本身的protected成员,因而只有其本身,子类,和友元可以访问)。而private继承自父类的子类只能在其本身作用域,其友元中可以绑定到父类的指针和引用(继承访问修饰符使得父类的public成员变成它本身的private成员,因而只有其本身,友元可以访问。任何时候,对象可执行的操作都只由其静态类型决定。

C++中还存在不完全类型,任何类型的完整定义未结束之前,都属于不完整类型,不完整类型可以用作函数声明的参数和返回值,可以用作定义该类型指针和引用,可以用于声明其为某类型的static成员。但不能通过该类型指针和引用访问该类型成员,也不能定义该类型对象(因此,不存在有本身类型的nonstatic成员的类型,其成员函数内部可以做任何事情)。由于类型的使用一般都需要整体定义完整出现,故而通常定义在头文件中。

二、对象的定义和声明

简而言之,对象的定义是为指定的对象名创建一个指定类型的对象实体,因此需要为该对象分配存储空间,并进行初始化。而对象的声明则是将某个对象实体的类型和对象名告知某个作用域。对于全局空间内变量和普通函数而言,其定义在全局作用域内必须唯一,其声明可以多次出现,但声明和定义必须一致,因此其定义一般出现且只出现在一个源文件中,而声明则出现在头文件中,从而保证了唯一的定义和一致的声明,以后如果定义有变化,也只需要修改一处声明。同时,定义所在的源文件一般要包含声明所在的头文件,从而协助编译器检查定义和声明的一致性。由于全局空间内的常量默认具有文件作用域,不同的源文件可以拥有同名常量,分属于不同实体;inline函数需要插入到调用点,其定义需要在调用处可见,因此const对象和inline函数一般定义在头文件中。对象的声明需要加extern关键词,以示编译器对象定义在别处,不要为对象分配内存空间,对象的定义自然起到了对象声明的作用,任何对象声明一旦被初始化即被视为对象的定义。函数的定义必须有函数体,而函数的声明则不能出现函数体。

三、对象的初始化和赋值:

C++中初始化和赋值是完全不同的两个概念,初始化是在一个对象创建时提供其创建的参数,而赋值则是对一个已存在对象的值进行修改;在类类型中,两者调用不同的函数,初始化一定是通过构造函数进行的,因为对象创建的限定接口为构造函数。而赋值则一定是通过赋值运算符进行的,对一个已存在的对象不可再次调用构造函数。由于const对象不可调用赋值运算符,因此在创建时必须提供显式初始化,引用类型属于终生绑定,从一而终,因此也必须提供显示初始化。

C++中初始化的方式:

两种隐式初始化

1)默认初始化:

初始化情景:未进行任何显示初始化的局部nonstatic对象定义(包括数组),动态分配的未显式初始化内存全部采用默认初始化。

初始化方式:类类型调用默认构造函数,无默认构造函数的类类型不可默认初始化,内置类型未定义

2)值初始化:

初始化情景:未进行任何显示初始化的全局对象和局部static对象定义(包括数组),部分初始化的数组其剩余未初始化的值采用值初始化。

初始化方式:类类型调用默认构造函数,无默认构造函数的类类型不可值初始化,内置类型初始化为0值

三种显式初始化

3)直接初始化:

初始化情景:显式使用ObjName(Initializers...)形式进行初始化,调用容器类的emplace打头的函数,make_shared<T>函数,make_pair<Tk,Tv>函数等都采用直接初始化创建对象。

初始化方式:对于类类型直接调用与实参匹配的构造函数,内置类型初始化为Initializer的值

4)复制初始化:

初始化情景:显示使用ObjName = Initializer 形式的初始化,普通(非引用)函数参数、返回值的传递等都采用复制初始化。

初始化方式:复制初始化的初始化物只能有一个,对于类类型总是调用其复制构造函数,复制初始化首先使用指定构造函数创建一个临时对象,然后用复制构造函数将那个临时对象复制到正在创建的对象。对于内置类型和直接初始化相同。

5)列表初始化:

初始化情景:显示使用ObjName{Initializers...}或者ObjName={Initializers...}进行初始化,或者提供的函数实参或返回值为{Initializers...}时

初始化方式:对于类类型,其要么必须具有形参为initializer_list类型的构造函数,要么必须足够简单,后一种情况不常遇到,我也不记得有哪些约束。对于内置类型,不可以降低精度,即int{double}形式的初始化是非法的。

时间: 2024-08-12 17:32:22

c++总结之类型,对象的定义和声明,对象的初始化和赋值的相关文章

GO学习笔记 - 变量在定义时没有明确的初始化时会赋值为“零值 ”。

官方教程:https://tour.go-zh.org/basics/12 变量在定义时没有明确的初始化时会赋值为 零值 . 零值是: 数值类型为 0 , 布尔类型为 false , 字符串为 "" (空字符串). 官方示例: package main import "fmt" func main() { //下面声明的变量没有被初始化,但是也具有值,就是默认的零值 var i int var f float64 var b bool var s string fm

对象---声明对象的方式

对象可以分为:1.内建对象:由ES标准中定义的对象,在任何的ES实现中都可以使用,比如:Math String Number Boolen Function等等 2.宿主对象:有JS的运行环境提供的对象,目前来讲主要指浏览器提供的对象,如:BOM DOM 3.自定义对象:由开发人员自己创建的对象 下面将对自定义对象进行讲解 声明对象的方式有:    1.字面式声明对象                           2.new操作符后跟Object构造函数声明对象              

JavaScript定义类与对象的一些方法

最近偶然碰到有朋友问我"hoisting"的问题.即在js里所有变量的声明都是置顶的,而赋值则是在之后发生的.可以看看这个例子: 1 var a = 'global'; 2 (function () { 3     alert(a); 4     var a = 'local'; 5 })(); 大家第一眼看到这个例子觉得输出结果是什么?'global'?还是'local'?其实都不是,输出的是undefined,不用迷惑,我的题外话就是为了讲这个东西的. 其实很简单,看一看JavaS

获取创建SQL Server对象的定义文本

引用自<SQL Server 2012 Internals> "   As views, these metadata objects are based on an underlying Transact-SQL (T-SQL) defnition. The most straightforward way to see the defnition of these views is by using the object_defnition function. (You can

【05】 定义类或对象

ECMAScript 定义类或对象 ECMAScript 拥有很多创建基类的方法. (就是说,可以任意的创建类似其他语言的“类”的概念.来创造不同模具,来形成模型.实例,就是我们所谓的模型) 一:原始方式(魔芋:最简单的方式.缺点:无法创建多个实例.此时,对象无法作为模具.) 因为对象的属性和方法可以在对象创建后动态定义,可以编写下面的代码: (魔芋:创建一个对象后,可以任意在很多位置给它添加属性和方法.) var Car=newObject; Car.color ="blue"; C

javascript学习笔记---ECMAScriptECMAScript 对象----定义类或对象

使用预定义对象只是面向对象语言的能力的一部分,它真正强大之处在于能够创建自己专用的类和对象. ECMAScript 拥有很多创建对象或类的方法. 原始的方式 因为对象的属性可以在对象创建后动态定义(后绑定),类似下面的代码: var oCar = new Object; oCar.color = "blue"; oCar.doors = 4; oCar.mpg = 25; oCar.showColor = function() { alert(this.color); };不过这里有一

面向对象基础——类与对象的定义

面向对象的概念 封装性:对外部不可见.可以保护程序中的某些内容. 继承性:扩展功能的. 类与对象的关系: 定义类和对象的方法? 类图的画法:Person类图 分为三层: 第一层表示类的名称,类的名称与之前一样要求开头首字母大写. 第二层表示属性的定义,按照" 访问权限 属性名称:属性类型 " 的格式定义: 第三层表示类中方法的定义,按照"  访问权限 方法名称():方法返回值类型  " 的格式定义.如下图所示: 类与对象的进一步研究 掌握Java中的内存划分,jav

C++中如何定义类和对象?

在C++语言中,对象的类型被称为类,类代表了某一批对象的共性和特征. 类是对象的抽象,而对象是类的具体实例.如同C中的结构体一样,我们要先定义一个结构体,再使用结构体去定义一个变量.同一个结构体可以定义出多个不同的结构体变量.我们要使用类也是如此. 类是对象的模板,如同我们在建造房屋时候的图纸,然后我们就可以利用这个图纸去建造许多个房屋.我们可以使用别人已经定义好的类.更多的时候,我们要根据需要定义自己的类. 定义类 定义结构体的方法: struct Student { char name[12

三种存储类型比较-文件、块、对象存储

块存储和文件存储是我们比较熟悉的两种主流的存储类型,而对象存储(Object-based Storage)是一种新的网络存储架构,基于对象存储技术的设备就是对象存储设备(Object-based Storage Device)简称OSD. 首先,我们介绍这两种传统的存储类型.通常来讲,所有磁盘阵列都是基于Block块的模式,而所有的NAS产品都是文件级存储. 1.块存储 以下列出的两种存储方式都是块存储类型: 1) DAS(Direct Attach STorage):是直接连接于主机服务器的一