C++学习之 类
1、类规范
- 类声明:包括数据成员、成员函数(共有接口)的声明
- 类方法定义
C++程序员将接口(类)放在头文件中,将实现放在源代码文件中
类设计尽量将共有接口和实现细节分开,数据隐藏(将数据放在私有部分中)是一种封装,将实现细节隐藏在私有部分中也是一种封装。将类函数定义和类声明放在不同文件中也是一种封装
注:类方法默认是内联函数
2、访问控制符
类默认的访问控制符是private
3、类和结构体
类和结构的区别是:
1、结构的默认访问类型是public,而类为private。
2、结构体在声明变量时,可以直接像标准类型那样初始化,而类需要构造函数进行初始化,当所有成员变量都是public修饰时,可以像struct那样初始化对象
如:
int a = 2;
struct node
{
int a;
string s;
}; node n = {3,"abc"};
Stock hot = {2,"abc"};//编译错误
C语言中结构体不允许定义函数成员,且没有访问控制符的概念。
C++为C语言中的结构体引入了成员函数、访问控制符、继承、包含多态等面向对象特性
C++保留struct结构体原因:C++在struct之外引入了class关键字,但为了保持与C程序的兼容,C++保留了struct关键字,并规定默认访问权限为public
另外,在C语言中,空结构体的大小为0,而在C++中空结构体(属于空类)的大小为1
C++中空类的大小为1的原因:
空类也可以实例化,类实例化出的每个对象都需要有不同的内存地址,为使每个对象在内存中的地址不同,所以在类中会加入一个隐含的字节
默认构造函数
默认构造函数是在未提供显示初始值时,用来创建对象的构造函数。默认构造函数可能是这样,比如:
Stock::Stock() {}
默认构造函数没有参数,因为声明中不包含值
当且仅当没有定义任何构造函数时,编译器才提供默认构造函数,为类定义了构造函数后,程序员就必须为它提供默认构造函数。如果提供了非默认构造函数,而没有提供默认构造函数,则下面的声明会出错:
Stock stock1;
这样做的原因可能是想禁止创建未初始化的对象,然而,如果要创建对象,而不是显式地初始化,则必须定义一个不接受任何参数的默认构造函数。定义默认构造函数的方式有两种。一种是给已有的构造函数的所有参数提供默认值:
Stock(const string &co = "Error",int n = 0,double pr = 0.0);
另一种方式是通过函数重载来定义另一个构造函数--一个没有参数的构造函数:
Stock();
由于只能有一个默认构造函数,因此不要同时采用这两种方式。
在设计类时,通常应提供对所有类成员做隐式初始化的默认构造函数
如:
Stock::Stock()
{
company = "no name";
shares = ;
share_val = 0.0;
total_val = 0.0;
}
析构函数
析构函数完成清理工作,如果构造函数使用new来分配内存,则析构函数将使用delete来释放这些内存
析构函数的调用:
- 如果创建的是静态存储类对象,则其析构函数将在程序结束时自动被调用
- 如果创建的是自动存储类对象,则其析构函数将在程序执行完代码块时自动被调用
- 如果对象是通过new来创建的,则它将驻留在栈内存或自由存储区中,当使用delete来释放内存时,其析构函数将自动被调用
例子:
Stock stock1("abc",,20.0);
创建一个名为stock1的对象,并将其数据成员初始化为指定的值
下面的语句使用另一种语法创建并初始化一个名为stock2的对象:
Stock stock2 = Stock("Boffo",,2.0)
这种方法可能创建临时对象,也可能不创建临时对象
另一种方式是创建一个临时对象,然后将临时对象赋值到stock2中,并丢弃它,如果编译器使用的是这种方式,则将为临时对象调用析构函数
Stock st1("Nanosmart",,20.0);
Stock st2 = Stock("Bob",,2.0);
st1 = Stock("Niffy",,50.0);//将创建临时对象,并复制给st1
析构函数的调用顺序是按声明顺序的栈序列进行的,即先声明的对象,后析构
C++11列表初始化
C++11中,可将列表初始化语法用于类,只要提供与某个构造函数的参数列表匹配的内容,并用大括号将它们括起:
Stock hot_tip = {"Derivatives Plus Plus",,45.0};
Stock jock {"Sport Age Storage,Inc"};
Stock temp {};
在前两个声明中,用大括号括起来的列表与下面的构造函数匹配:
Stock::Stock(const std::string &co, long n = , double pr = 0.0);
const成员函数
const Stock land = {"Kludgehorn Properties"};
land.show();
对于C++来说,编译器将拒绝第二行,因为show()的代码无法确保调用对象不被修改
需要一种新的语法,保证函数不会修改调用对象。C++的解决方法是将const关键字放在函数的括号后面,如
void show() const;
函数定义的开头应该这样:
void stock::show() const
以这种方式声明和定义的类函数被称为const成员函数(防止方法调用修改对象)
对象数组
用户通常要创建同一个类的多个对象,可以创建独立对象变量,也可以创建对象数组:
Stock mystuff[];
当程序创建未被显式初始化的类对象时,总是调用默认构造函数,可以用构造函数来初始化数组元素,这种情况下,必须为每个元素调用构造函数:
const int STKS = ;
Stock stock[STKS] = {
Stock("NanoSmart",12.5,),
Stock("Boffo Objects",,2.0),
Stock("Monolithic Obelisks",,3.25),
Stock("Fleep Enterprises",,6.5)
};
这里的代码使用标准格式对数组进行初始化:用括号括起来的、以逗号分隔的值列表,括号里面的每个对象都是临时对象,然后将值复制给数组元素
初始化对象数组的方案是
- 首先使用默认构造函数创建数组元素
- 然后花括号中的构造函数将创建临时对象
- 然后将临时对象的内容复制到相应的元素中
因此,要创建类对象数组,则这个类必须有默认构造函数
作用域为类的常量
有时候,使符号常量的作用域为类很有用,因此创建一个由所有对象共享的常量是个不错的主意
class Bakery
{
private:
const int Months = ;
double costs[Months];
...
}
但这样是行不通的,因为声明类只是描述了对象的形式,并没有创建对象,因此在创建对象前并没有用于存储值得空间
第一种方式是在类中声明一个枚举,在类声明中声明的枚举的作用域为整个类,因此可以用枚举为整型常量提供作用域为整个类的符号名称,如
class Bakery
{
private:
enum {Months = ;};
double costs[Months];
...
}
用这种方式声明枚举不会创建类数据成员,也就是说,所有对象中都不包含枚举,Months只是一个符号名称,在作用域为整个类的代码中遇到它时,编译器将用12来代替它
C++提供了另一种在类中定义常量的方式--使用关键字static:
class Bakery
{
private:
static const int Months = ;
double costs[Months];
...
}
这将创建一个名为Months的常量,该常量与其他静态变量存储在一起,而不是存储在对象中,因此,只有一个Months常量,被所有Bakery对象共享
C++学习之 类的更多相关文章
- Java虚拟机JVM学习07 类的卸载机制
Java虚拟机JVM学习07 类的卸载机制 类的生命周期 当Sample类被加载.连接和初始化后,它的生命周期就开始了. 当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就 ...
- Java虚拟机JVM学习04 类的初始化
Java虚拟机JVM学习04 类的初始化 类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始 ...
- Java虚拟机JVM学习02 类的加载概述
Java虚拟机JVM学习02 类的加载概述 类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对 ...
- Java学习-023-Properties 类 XML 配置文件读取及写入源代码
之前的几篇 Properties 文章已经讲述过了 Java 配置文件类 Properties 的基本用法,查看 JDK 的帮助文档时,也可看到在 Properties 类中还有两个方法 loadFr ...
- 再次学习C++类之构造函数
学习C++类,首先要说C中的结构体,虽然C++类扩展了C中的结构体,可以添加成员函数,但他们是有区别的.在结构体中,成员变量.成员函数都是公有的,而类中,一般是成员变量是私有的,成员函数是公有的,私有 ...
- (转) 学习C++ -> 类(Classes)的定义与实现
学习C++ -> 类(Classes)的定义与实现 一."类" 的介绍 在C++中, 用 "类" 来描述 "对象", 所谓的&q ...
- Javascript学习6 - 类、对象、继承
原文:Javascript学习6 - 类.对象.继承 Javasciprt并不像C++一样支持真正的类,也不是用class关键字来定义类.Javascript定义类也是使用function关键字来完成 ...
- Python学习:类和实例
Python学习:类和实例 本文作者: 玄魂工作室--热热的蚂蚁 类,在学习面向对象我们可以把类当成一种规范,这个思想就我个人的体会,感觉很重要,除了封装的功能外,类作为一种规范,我们自己可以定制的规 ...
- 《python基础教程(第二版)》学习笔记 类和对象(第7章)
<python基础教程(第二版)>学习笔记 类和对象(第7章) 定义类class Person: def setName(self,name): self.name=n ...
- Java学习——枚举类
Java学习——枚举类 摘要:本文主要介绍了Java的枚举类. 部分内容来自以下博客: https://www.cnblogs.com/sister/p/4700702.html https://bl ...
随机推荐
- SQL SERVR 逻辑函数
IIF: 根据布尔表达式计算为 true 还是 false,返回其中一个值. IIF 是一种用于编写 CASE 表达式的快速方法. 它将传递的布尔表达式计算为第一个参数,然后根据计算结果返回其他两个参 ...
- node学习笔记_02 API详解
一.知识点:url.parse方法 方法说明: 讲一个URL字符串转换成对象并返回. 语法:url.parse(urlStr, [parseQueryString], [slashesDenoteHo ...
- Spark2.3文档翻阅的一点简略笔记(WaterMarking)
写本文原因是之前已经将官网文档阅读过几遍,但是后来工作接触spark机会较少所以没有跟进新特性,利用周末一点闲暇时间粗略阅读一篇,将自己之前遇见过的问题解决过的问题印象不深刻的问题做一下记录. 1关于 ...
- shiro实战系列(五)之Authentication(身份验证)
建议学习shiro读读官方文档,虽然不一定读的懂,但是建议要大致浏览,心中有个大概,这样对于学习还是有一定帮助 官网地址:https://shiro.apache.org/ Authenticatio ...
- 谷歌开源漏洞跟踪工具 Monorail 存在跨站点搜索漏洞
一名安全研究员表示,在谷歌开源漏洞跟踪工具 Monorail 中找到一个漏洞,可被用于执行跨站点搜索 (XS-Search) 攻击. Monorail 用于检查和 Chromium 相关项目中的问题, ...
- python变量的引用,浅拷贝
python的变量是对象引用 l1和l2引用的相同的对象,所以会相互影响 元组不变的是引用的物理地址,如果引用的对象是可变的,那么远祖也会发生变化 但是t1[2]的id时钟没有发生变化 2 默认是浅拷 ...
- 1-关于单片机通信数据传输(中断发送,大小端,IEEE754浮点型格式,共用体,空闲中断,环形队列)
补充: 程序优化 为避免普通发送和中断发送造成冲突(造成死机,复位重启),printf修改为中断发送 写这篇文章的目的呢,如题目所言,我承认自己是一个程序猿.....应该说很多很多学单片机的对于... ...
- stm32_DMA采集一个AD数据_并通过DMA向串口发送
这是以前学32的时候写的,那时候学了32之后感觉32真是太强大了,比51强的没影.关于dma网上有许多的资料,关于dma采集ad网上也有很多.亲们搜搜,这里只贴代码了,其实我也想详详细细地叙述一番,但 ...
- group by having 和where区别联系
原文参考:http://www.51ou.com/browse/msyql/43081.html having 和 where 参考 http://blog.csdn.net/yexudengzhid ...
- 怎样让oracle实验本在不做实验时性能提升——win7下举例
怎样让oracle实验本在不做实验时性能提升--win7下举例 型号:ThinkPad E431 系统:WIN7 实验使用的笔记本不使用数据库时.建议将oracle关闭,使其释放占用的资源. orac ...