码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2014-11-17 14:07:43      阅读:451      评论:0      收藏:0      [点我收藏+]

标签: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}形式的初始化是非法的。





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

标签:c++   对象      

原文地址:http://blog.csdn.net/yuanliang01xiaolang/article/details/41207249

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!