类是一种数据类型,它类似于普通的数据类型,但是又有别于普通的数据类型。类这种数据类型是一个包含成员变量和成员函数的一个集合。

类的成员变量和普通变量一样,也有数据类型和名称,占用固定长度的内存空间。但是,在定义类的时候不能对成员变量赋值,因为类只是一种数据类型,本身不占用内存空间,而变量的值则需要内存来存储。

类的成员函数也和普通函数一样,都有返回值和参数列表,它与一般函数的区别是:成员函数是一个类的成员,出现在类体中,它的作用范围由类来决定;而普通函数是独立的,作用范围是全局的,或位于某个命名空间内。

上节我们在最后的完整示例中给出了 Student 类的定义,如下所示:

 class Student{
public: //类包含的变量
char *name;
int age;
float score;
public: //类包含的函数
void say(){
printf("%s的年龄是 %d,成绩是 %f\n", name, age, score);
}
};

上面的代码在类体中定义了成员函数。你也可以只在类体中声明函数,而将函数定义放在类体外面,如下图所示:

class Student{
public:
char *name;
int age;
float score;
public:
void say(); //函数声明
};
//函数定义
void Student::say(){
printf("%s的年龄是 %d,成绩是 %f\n", name, age, score);
}

在类体中直接定义函数时,不需要在函数名前面加上类名,因为函数属于哪一个类是不言而喻的。

但当成员函数定义在类外时,就必须在函数名前面加上类名予以限定。::被称为域解析符(也称作用域运算符或作用域限定符),用来连接类名和函数名,指明当前函数属于哪个类。

如果在域解析符“::”的前面没有类名,或者函数名前面既无类名又无域解析符“::”,如:

//无类名
::say( ){
//TODO
}
//无类名也无域解析符
say( ){
//TODO
}

则表示 say() 函数不属于任何类,这个函数不是成员函数,而是全局函数,即非成员函数的一般普通函数。

成员函数必须先在类体中作原型声明,然后在类外定义,也就是说类体的位置应在函数定义之前,否则编译时会出错。

inline 成员函数

在类体中和类体外定义成员函数是有区别的:在类体中定义的成员函数为内联(inline)函数,在类体外定义的不是。

内联函数一般不是我们所期望的,它会将函数调用处用函数体替代,所以我建议在类体内部对成员函数作声明,而在类体外部进行定义,这是一种良好的编程习惯。

如果你既希望将函数定义在类体外部,又希望它是内联函数,那么可以在声明函数时加 inline 关键字,如下所示:

在类体内部定义的函数也可以加 inline 关键字,但这是多余的,因为类体内部定义的函数默认就是内联函数。

值得注意的是,如果在类体外定义 inline 函数,则必须将类定义和成员函数的定义都放在同一个头文件中(或者写在同一个源文件中),否则编译时无法进行嵌入(将函数代码的嵌入到函数调用出)。这样做虽然提高了程序的执行效率,但从软件工程质量的角度来看,这样做并不是好的办法,因此实际开发中较少在类中使用内联函数。

C++类成员的访问权限

C++通过 public、protected、private 三个关键字来控制成员变量和成员函数的访问权限,它们分别表示公有的、受保护的、私有的,被称为成员访问限定符。所谓访问权限,就是你能不能使用该类中的成员

访问权限需要分两部分说明:类内和类外。

  • 在类内部,无论成员变量或成员函数被声明为 public、protected 还是 private,都是可以互相访问的,无访问权限限制。
  • 在类外部,通过对象无法访问 private、protected 属性的成员变量和成员函数,而仅可以访问 public 属性的成员变量和成员函数。
#include <stdio.h>
class Student{
private:
char *name;
int age;
float score;
public:
void setname(char *name1){
name = name1;
}
void setage(int age1){
age = age1;
}
void setscore(float score1){
score = score1;
}
void say(){
printf("%s的年龄是 %d,成绩是 %f\n", name, age, score);
}
};
int main(){
Student stu;
stu.setname("小明");
stu.setage();
stu.setscore(92.5f);
stu.say();
return ;
}

类中的成员变量 name、age 和 score 被设置成 private 属性,在类外部的代码都不能访问,即使通过该类创建的对象也不行。也就是说,私有成员变量和成员函数只能在类内部使用,在类外都是无效的。

成员函数 setname()、setage() 和 setscore() 被设置为 public 属性,是公有的,可以通过对象访问。

因为三个成员变量都是私有的,不能通过对象直接访问,所以必须借助三个 public 属性的成员函数来修改它们的值。

private 成员的作用在于更好地隐藏类的内部实现,该向外暴露的接口都声明为 public,不希望外部知道、或者只在类内部使用的、或者对外部没有影响的成员,都建议声明为 private,这样的代码更加符合软件设计规范。

另外还有一个关键字 protected,声明为 protected 属性的成员变量或成员函数,在类外也是不可以访问的,但是其派生类内部可以访问,我们将在后续章节介绍,在这里你只需要知道 protected 在类外无法访问即可。

两点说明:
1) 声明为 private 的成员和声明为 public 的成员的次序任意,既可以先出现 private 部分,也可以先出现 public 部分。如果既不写 private 也不写 public,就默认为 private。

2) 在一个类体中,private 和 public 可以分别出现多次。每个部分的有效范围到出现另一个访问限定符或类体结束时(最后一个右花括号)为止。但是为了使程序清晰,应该养成这样的习惯,使每一种成员访问限定符在类定义体中只出现一次。

C++学习6的更多相关文章

  1. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  2. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  3. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  4. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  5. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  6. Unity3d学习 制作地形

    这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...

  7. 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...

  8. 菜鸟Python学习笔记第一天:关于一些函数库的使用

    2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...

  9. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

  10. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

随机推荐

  1. 数据库之mysql

    安装mysql-server时连同客户端与perl环境一起安装了 centos6.5安装mysql[root@localhost ~]# yum install mysql-server Instal ...

  2. 【转】[NOIP2003普及组]麦森数

    来源:http://vivid.name/tech/mason.html 不得不纪念一下这道题,因为我今天一整天的时间都花到这道题上了.因为这道题,我学会了快速幂,学会了高精度乘高精度,学会了静态查错 ...

  3. python str()与repr()

    相同点: 将任意值转为字符串 不同点: str()致力于生成一个对象的可读性好的字符串表示,它的返回结果通常无法用于eval()求值,但很适合用于print语句输出 repr()出来的值是给pytho ...

  4. 关闭Outlook时最小化

    公司用的是阿里邮箱,foxmail客户端总是把已读邮件又标记成未读,又赶上最近招聘,真是深受其烦.已经无法忍受了,决定换了它,重新用起最强客户端outlook. Outlook解决了foxmail的问 ...

  5. ubuntu- eclipse、CDT安装

    eclipse的安装: 应用程序->附件->终端                                       然后输入(中间可能需要你输入密码):              ...

  6. MyEclipse Hibernate 学习总结

    最近在学习Hibernate,先把学习的过程记录一下,方便自己以后复习. 1.使用工具 MyEclipse 10 2. 1)新建Java程序 2)右键程序,选择MyEclipse-> Add H ...

  7. [原]在Fedora中编译Libevent测试实例

    在我的昨天的博文<[原]我在Windows环境下的首个Libevent测试实例>中介绍了在Windows环境下如何编译一个echo server例子.今天我又试了一下在Linux环境中编译 ...

  8. HTML 文本格式化

    HTML 可定义很多供格式化输出的元素,比如粗体和斜体字. 下面有很多例子,您可以亲自试试: HTML 文本格式化实例 文本格式化 此例演示如何在一个 HTML 文件中对文本进行格式化 预格式文本 此 ...

  9. win8以管理员身份安装软件

    win8以管理员身份安装软件 msiexec /package

  10. 黄聪:wordpress如何扩展TinyMCE编辑器,添加自定义按钮及功能

    在functions.php文件里面添加: add_action( 'admin_init', 'my_tinymce_button' ); function my_tinymce_button() ...