C++学习系列文章均翻译自learncpp.com,一个非常好的C++学习网站,这个网站让我领悟到原来深奥的道理也可以讲的如此浅显易懂, 如果所有的软件都有类似的网站该多好啊,为了加深印象,我决定逐章翻译一下这个网站,哎,我自己都不相信我能做到...

C++提供了一些基本的数据类型(例如:char, int, long, float, double, 等等...),这些类型在处理相对简单的问题时通常是可以满足需要的,但是仅仅使用这些类型在解决复杂的问题时就会比较困难。C++的一个常用的特性就是可以自定义数据类型,以便更好的对应需要解决的问题。在之前的章节你已经看到了如何使用枚举及结构来创建你自己的数据类型。

下面是一个用结构来存储数据的例子:

struct DateStruct
{int year;int month;int day;
};

枚举类型及只包含数据的结构(结构里只包含变量)代表了传统的非面向对象编程的世界,因为他们只保存数据。在C++11中,我们可以按如下方式创建并初始化该结构:

DateStruct today { 2020, 10, 14 } ; // use uniform initialization

现在,如果我们希望在屏幕上打印数据的内容(我们可能经常会执行的操作),可以写一个函数来完成这个工作。全部代码如下:

#include <iostream>struct DateStruct
{int year;int month;int day;
};void print(DateStruct &date)
{std::cout << date.year << "/" << date.month << "/" << date.day;
}int main()
{DateStruct today { 2020, 10, 14}; // use uniform initialization
today.day = 16; // use member selection operator to select a member of the struct
  print(today);return 0;
}

这段代码将输出如下内容:

2020/10/16

在面向对象编程的世界里,我们通常期望我们的数据类型不只储存数据,而是同时包括处理这些数据的函数。在C++中,这种类型的变量通过class关键字来声明。用class关键字可以定义一个被称为类的新的用户自定义类型。

在C++中,类与只包含数据的结构很像,除此之外类还提供了更强的功能及灵活性。事实上,下面的结构与类实际上是相同的:

 1 struct DateStruct
 2 {
 3     int year;
 4     int month;
 5     int day;
 6 };
 7
 8 class DateClass
 9 {
10 public:
11     int m_year;
12     int m_month;
13     int m_day;
14 };

请注意最大的区别是class中的public关键字。我们将在下一节中讨论这个关键字。

和声明一个结构相同,声明一个类并不会分配任何内存。它只是定义了类看起来是什么样子的。

警告:像结构一样,在C++中最容易犯的一个错误就是在类声明结束时忘记打分号。这将导致一个指向下一行的编译错误。最新的编译器比如Visual Studio 2010会给你一些指导,告诉你你可能忘记了分号,但是较早的或功能不够强大的编译器可能不会给出这些提示,这将导致很难发现真正的错误所在。

和声明一个结构一样,必须要声明一个改class类型的变量:

1 DateClass today {2020, 10, 14}; // declare a variable of class DateClass

在C++中当我们定义一个class类型的变量时,我们称之为类的实例化。这个变量被成为该类的一个实例。一个class类型的变量也被称为一个对象。像定义一个内部变量(例如:int x)时系统会为该变量分配内存,实例化一个对象(例如:DateClass today)时系统也会为该对象分配内存。

成员函数

除了包括数据外,类也可以包括函数。class中定义的函数被称为成员函数。下面的例子中我们的Data类包括了一个用来打印日期的成员函数:

 1 class DateClass
 2 {
 3   public:
 4      int m_year;
 5      int m_month;
 6      int m_day;
 7
 8      void print() // defines a member function named print()
 9      {
10        std::cout << m_year << "/" << m_month << "/" << m_day;
11      }
12 };

像结构的成员一样,类的成员(变量及函数)通过(.)操作符访问:

 1 #include <iostream>
 2
 3 class DateClass
 4 {
 5 public:
 6     int m_year;
 7     int m_month;
 8     int m_day;
 9
10     void print()
11     {
12         std::cout << m_year << "/" << m_month << "/" << m_day;
13     }
14 };
15
16 int main()
17 {
18     DateClass today { 2020, 10, 14 };
19
20     today.m_day = 16; // use member selection operator to select a member variable of the class
21     today.print(); // use member selection operator to select a member function of the class
22
23     return 0;
24 }

运行结果:

2020/10/16

你可能注意到上面的代码和我们之前使用结构的版本多么的相似。

但是,也有一些区别。在使用结构的版本中,我们需要把结构本身作为一个参数传递给print()函数。否则的话print()函数不知道我们要处理的是哪个DateSturct结构。

但是,在我们类版本的print()中,我们不需要传递要打印的DataClass!因为print()是通过class类型的变量"today"调用的,print()函数中的成员变量将指向class类型的变量today!于是,在today.print()函数内部,m_day实际上指向了today.m_day。如果我们调用tomorrow.print(),print()中的m_day将指向tomorrow.m_day.

成员变量使用m_作为前缀可以帮助区分开成员变量与函数形参或本地变量。这样做的好处有几个。第一,当我们看到给m_作为前缀的变量赋值时,我们就知道我们在改变类的状态。第二,与在本地定义的函数形参及本地变量不同,成员变量是在类的内部定义的。于是如果我们想查看以m_开头的变量的类型定义,我们不能在函数内部找,而是要在类的定义中找。

按照惯例,类的名称的首字母应该大写。

规则:定义类时首字母大写

下面是定义类的另一个例子:

 1 #include <iostream>
 2 #include <string>
 3
 4 class Employee
 5 {
 6 public:
 7     std::string m_name;
 8     int m_id;
 9     double m_wage;
10
11     // Print employee information to the screen
12     void print()
13     {
14         std::cout << "Name: " << m_name <<
15                 "  Id: " << m_id <<
16                 "  Wage: $" << m_wage << '\n';
17     }
18 };
19
20 int main()
21 {
22     // Declare two employees
23     Employee alex { "Alex", 1, 25.00 };
24     Employee joe { "Joe", 2, 22.25 };
25
26     // Print out the employee information
27     alex.print();
28     joe.print();
29
30     return 0;
31 }

输出结果如下:

Name: Alex Id: 1 Wage: $25

Name: Joe Id: 2 Wage: $22.25

和一般的函数不同,成员函数的定义顺序没有影响!

关于C++中的结构

在C语言中,structs只能保存数据,而不能包含成员函数。在C++语言中,在设计完class之后,Bjarne Stroustrup花了一段时间考虑是否structs(继承自C语言)也应该被赋予相同的功能。经过一番考虑,他决定他们应该具有相同的规则集。所以虽然我们在写上面的程序时使用了class关键字,但是我们也可以使用struct关键字来代替。

许多开发者(包括我自己在内)感觉这是一个错误的决定,因为它可能导致危险的假设:例如,假设一个class会回收自己是合理的(比如一个class会在失效后释放其分配的内存),但是假设sturct也会这样做是不安全的。相应的,我们建议struct关键字使用在只有数据的场合,而class关键字用来定义需要包括数据及函数的对象。

规则:使用struct关键字在只有数据的结构。使用class关键字定义包括数据和函数的对象。

结论

Class关键字让我们可以在C++中创建包括成员变量和成员函数的自定义类型。Class构成了面向对象编程的基础,我们将在本章之后的内容及之后的许多章节来探索class必须提供的功能。

转载于:https://www.cnblogs.com/lukecui/p/6063700.html

C++学习 8.2 - 类及类成员相关推荐

  1. C++ 学习 ::【基础篇:13】:C++ 类的基本成员函数:类类型成员的初始化与构造函数问题

    本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段:基础篇.STL 篇.高阶数据结构与算法篇,相关重点内容如下: 基础篇:类与对象(涉及C++的三大特 ...

  2. 尚硅谷第五天课0722班 java-面向对象学习的三条主线-面向对象的思想概述- 类的元素- java类及类的成员-类的成员之方 法

    面向对象学习的三条主线:* 1.类和类的组成(属性(或成员变量).方法.构造器:代码块(或初始化块).内部类)* 2.面向对象的特征:封装与隐藏.继承性.多态性.(抽象性)* 3.其它关键字的使用:t ...

  3. 在保护继承中基类的共有成员_C++学习大纲:继承方式的调整

    C++ 继承方式的调整 在任何继承方式中,除了基类的private成员外,都可以在派生类中分别调整其访问控制. 调整格式 [public: | protected: | private: ] :: ; ...

  4. 在保护继承中基类的共有成员_C++学习刷题13--继承的实现、继承的方式

    一.前言 本部分为C++语言刷题系列中的第13节,主要讲解这几个知识点:继承的实现.继承的方式.欢迎大家提出意见.指出错误或提供更好的题目! 二.知识点讲解 知识点1:继承的实现,可以理解派生类拥有成 ...

  5. php键顺序初始化,Java类中各成员初始化的顺序

    了解Java中类各个成员的初始化顺序是非常重要的,这样你可以对类有全局的认识.不说太多,直接看下面的例子 class Father { static{ System. out.println(&quo ...

  6. # C# 学习笔记(4) 类

    C# 学习笔记(4) 类 面向对象编程主要是为了写出一个通用的代码,屏蔽差异,方便开发大型项目.类就是面向对象编程的核心之一.和C语言的结构体相比,结构体拥有的功能,类统统都有,除此之外,类还有许多新 ...

  7. Python基础教程:类的特殊成员及高级特性

    1 对象的格式化输出 (1)如果需要对一个对象(实例)进行格式化输出,可以重写类的__repr__()和__str__()方法. 两者的区别:使用交互式解释器输出对象时,结果是__repr__()方法 ...

  8. 第13天学习Java的笔记(类定义)

    类和对象 类=属性+行为:类是抽象的,对象是具体化的. package Demo1301;/* 定义一个类,用来模拟"学生"事务.其中就有两个组成部分, 属性(是什么):成员变量( ...

  9. C++学习笔记:(一)面向对象 类与对象

    目录 1.面向对象的概念 2.类与对象 2.1 类的定义格式 2.2 对象的定义与使用 2.3 构造函数和析构函数 2.4 内存的动态分配 2.5 对象数组和对象指针 2.6 函数参数的传递机制 2. ...

  10. c++基础学习(07)--(类)

    文章目录 目录 类与对象 1.类成员函数 2.类访问修饰符 3.构造函数与析构函数 4.拷贝构造函数 5. 友元函数 6.内联函数 7.this指针 8.指向类的指针 9.类的静态成员 目录 类与对象 ...

最新文章

  1. Ubuntu 32下Android NDK+NEON的配置过程及简单使用举例
  2. 国产研发管理工具也在慢慢壮大,Worktile7岁了!
  3. ASP.NET MVC实践系列9-filter原理与实践
  4. wxDrawjs循环添加图形后增加标识记录点击的是哪个的另类方法
  5. sort uniq命令
  6. Win2000 Win2003安装卡巴斯基6.0
  7. 安卓开发必备知识体系:安卓篇
  8. wireshark网络分析就这么简单 pdf_才知道,PDF、Excel、Word互转这么简单?涨知识了...
  9. “云计算的前世今生·从阿里看云计算”内蒙古师范大学刘晨旭博士专题报告会顺利召开...
  10. 编译Android源码相关资源及文章
  11. linux 低功耗模式,stm32的低功耗模式:
  12. XCodeGhost
  13. 传奇服务器系统版本,[资料]服务端详细解释
  14. 安卓手机短信误删能恢复吗?
  15. 大数据技术在我们日常生活中的应用
  16. 讯飞语音转写php版demo
  17. 敏捷转型行动笔记:内部敏捷教练培训资料分享——认知篇(认识敏捷教练,摆正角色认知)
  18. JavaWeb图书馆管理系统的设计与实现
  19. 免费的音频编辑器为Mac用户
  20. 实现类似于头脑风暴的小游戏

热门文章

  1. NYOJ 588 Money
  2. 用计算机进行实时自动采集,《大学计算机基础》基础部分练习题_附件1
  3. python中的super用法详解_python中super的用法实例解析
  4. html5怎么插入一段文字,HTML5教程—文字插入进度动画_HTML5教程_文字插入_动画进度_课课家...
  5. 容器技术Docker K8s 34 容器服务ACK基础与进阶-安全管理
  6. 阿里云云计算 31在线实验--弹性伸缩(AS)初体验
  7. Swift App启动干了什么事情, 删掉UIApplicationMain,自定义实现main类, Main Runloop
  8. 497.非重叠矩形中的随机点
  9. 树中两个节点的最低公共祖先
  10. Servlet和JSP