• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 详解C++编程中类的成员变量和成员函数的相关知识

详解C++编程中类的成员变量和成员函数的相关知识

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c++指针详解,c++编程实例详解,c++关键字详解,c++编程实例详解pdf,c++ 虚函数详解等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

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

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

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

上节我们在最后的完整示例中给出了 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);
}
</div>

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

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

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

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


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

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

虽然成员函数在类的外部定义,但在调用时会根据在类中声明的函数原型找到函数的定义(函数代码),从而执行该函数。
inline 成员函数

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

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

当然,如果你的函数比较短小,希望定义为内联函数,那也没有什么不妥的。

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

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

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

C++提出内联函数的主要用意是:用内联函数取代带参宏定义(函数传参比宏更加方便易用),而不是提高程序运行效率,因为与执行函数花费的时间相比,调用函数花费的时间往往微乎其微。

C++成员函数的存储方式
用类去定义对象时,系统会为每一个对象分配存储空间。如果一个类包括了数据和函数,要分别为数据和函数的代码分配存储空间。

按理说,如果用同一个类定义了10个对象,那么就需要分别为10个对象的数据和函数代码分配存储单元,如下图所示。

能否只用一段空间来存放这个共同的函数代码段,在调用各对象的函数时,都去调用这个公用的函数代码。如图所示。

显然,这样做会大大节约存储空间。C++编译系统正是这样做的,因此每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间。如果声明了一个类:

class Time
{
  public:
  int hour;
  int minute;
  int sec;
  void set( )
  {
   cin>>a>>b>>c;
  }
};
</div>

可以用下面的语句来输出该类对象所占用的字节数:

  cout<<sizeof(Time)<<endl;
</div>


输出的值是12。

这就证明了一个对象所占的空间大小只取决于该对象中数据成员所占的空间,而与成员函数无关。

函数代码是存储在对象空间之外的。如果对同一个类定义了10个对象,这些对象的成员函数对应的是同一个函数代码段,而不是10个不同的函数代码段。需要注意的是,虽然调用不同对象的成员函数时都是执行同一段函数代码,但是执行结果一般是不相同的。

不同的对象使用的是同一个函数代码段,它怎么能够分别对不同对象中的数据进行操作呢?

原来C++为此专门设立了一个名为this的指针,用来指向不同的对象。需要说明:
不论成员函数在类内定义还是在类外定义,成员函数的代码段都用同一种方式存储。
不要将成员函数的这种存储方式和inMne(内置)函数的概念混淆。不要误以为用inline声明(或默认为inline)的成员函数,其代码段占用对象的存储空间,而不用 inline声明的成员函数,其代码段不占用对象的存储空间。不论是否用inline声明,成员函数的代码段都不占用对象的存储空间。用inline声明的作用是在调用该函数时,将函数的代码段复制插人到函数调用点,而若不用inline声明,在调用该函数时,流程转去函数代码段的人口地址,在执行完该函数代码段后,流程返回函数调用点。inline与成员函数是否占用对象的存储空间无关,它们不属同一个问題,不应搞混。
应当说明,常说的“某某对象的成员函数”,是从逻辑的角度而言的,而成员函数的存储方式,是从物理的角度而言的,二者是不矛盾的。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++的虚析构详解及实例代码
  • C++二分查找(折半查找)算法实例详解
  • C++ 中指针和引用有什么区别详解
  • C++ 中函数重载、覆盖与隐藏详解
  • C++中指针指向二维数组实例详解
  • C++调用Python基础功能实例详解
  • C++中this指针用法详解及实例
  • C++中函数重载实例详解
  • C++中指针和引用的区别详解
  • C++模版函数详解

相关文章

  • 2017-05-28C++学习小结之数据类型及转换方式
  • 2017-05-28VC取得任务栏高度的方法
  • 2017-05-28C语言打印华氏-摄氏温度对照表的方法
  • 2017-05-28深入探讨:main函数执行完毕后,是否可能会再执行一段代码?
  • 2017-05-28电脑开机时间的计算代码
  • 2017-05-28如何编译libfreetype方法详解
  • 2017-05-28基于结构体与指针的详解
  • 2017-05-28Windows的钩子机制详解
  • 2017-05-28c语言程序设计文件操作方法示例(CreateFile和fopen)
  • 2017-05-28浅谈VC中预编译的头文件放那里的问题分析

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 浅谈Windows系统下C语言编程中Glib库的使用
    • VC小技巧汇总之窗口技巧
    • C++多文件变量解析
    • 给ActiveX签名的实现方法详解
    • Qt定时器和随机数详解
    • C语言 函数指针(指向函数的指针)详解
    • typedef和#define的用法以及区别
    • 基于C++中常见编译错误的总结详解
    • 详解C++中基类与派生类的转换以及虚基类
    • 利用C语言实践OOP,以及new,delete的深入分析

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有