(25.2)类的定义之类的数据成员,类的成员函数,类的声明
文章目录
- 1.类的数据成员
- 2.类的成员函数
- 3.成员函数重载及默认参数
- 4.成员函数的存储方式
- 5.类的声明
1.类的数据成员
(1)在类中声明数据成员
正如我们所见, 类的数据成员的声明类似于普通变量的声明。 如果一个类具有多个同一类型的数据成员, 则这些成员可以在一个成员声明中指定。
class Cube //Cube类表示立方体
{… //其他成员long color; //数据成员double x,y,z,side; //数据成员
};
- 类的数据成员可以是基本类型、 数组、 指针、 引用、 共用体、 枚举类型、 void指针、 const限定等数据类型。 例如:
class ADT //类成员数据类型
{… //成员函数long color;double x,y,z,side; //基本类型int a[10]; //数组char *s; //指针char &r; //引用void *p; //void指针
};
- 类的数据成员还可以是成员对象(member object) , 即类类型或结构体类型的对象。 若类A中嵌入了类B的对象, 称这个对象为子对象(subobject) 。 例如: 类Line嵌入了类Point的子对象start、 end。
class Point //Point类表示点
{public:void set(int a,int b);int x,y;
};
class Line //Line类表示线
{public:void set(Point a,Point b);Point start, end; //成员对象
};
(2)在类中定义或声明数据类型
- 除了定义数据成员和成员函数之外, 类还可以定义自己的局部类型,并且使用类型别名来简化。
- 在类中定义或声明的数据类型的作用域是类内部, 因此, 它们不能在类外部使用。
- 在类定义中, 可以定义结构体和共用体类型、 嵌套的类定义, 声明枚举类型
eg:
class ADT //类定义
{struct Point //定义结构体{ int x,y; };union UData //定义共用体{Point p; long color; };enum COLORS {RED,GREEN,BLUE,BLACK,WHITE }; //定义枚举类型class Nested //嵌套类定义{… //成员函数Point start; //数据成员UData end; //数据成员COLORS color; //数据成员};typedef Point* LPPOINT; //声明类型别名… //成员函数… //数据成员
}; //类定义结束
2.类的成员函数
(1) 在类的外部定义成员函数
- 如果成员函数仅有声明在类定义中, 则在类外部必须有它的实现,其一般形式为:
返回类型 类名::函数名(形式参数列表)
{函数体
}
eg:
class Data//Data类定义
{public:void set(int d);//成员函数原型声明int get()//成员函数定义{ return data;}//get函数定义结束private:int data;//数据成员
};//Data类定义结束void Data::set(int d)//set函数所属于类Data,//成员函数的外部定义, 使用 Data:: 限定
{data=d;//访问类的数据成员
}
void set(int d)//全局普通函数
{,,,//函数体
}说明:
(1) (::) 是作用域限定符(field qualifed,常称之为域作用符)。 如果在作用域限定
符的前面没有类名, 或者函数前面既无类名又无作用域限定符, 例如:
::set(10) 或 set(10)
则表示set函数不属于任何类, 这个函数不是成员函数, 而是全局的普通函数。
此时的(::) 不是类作用域限定符的含义, 而是命名空间域限定符的含义。(2) 在成员函数中可以访问这个类的任何成员, 无论它是公有的或是私有的,
是类内部声明的还是类外部定义的。(3) 虽然成员函数在类的外部定义, 但在调用成员函数时会根据在类中声明的函数原型找到函数
的定义(即函数代码) , 从而执行该函数。 因此类的成员函数原型声明必须出现在成员函数定义之前,
否则编译时会出错。重点:(4) 在类的内部声明成员函数, 而在类的外部定义成员函数, 这是一个良好的编程习惯。 因为不
仅可以减少类体的长度, 使类体结构清晰, 便于阅读, 而且有助于类的接口和实现分离。
►(5) 如果一个成员函数, 其函数体不太复杂, 只有4~5行时, 一般可在类体中定义
(2)内联成员函数
- 类的成员函数可以指定为inline, 即内联函数。
- 默认情况下, 在类体中定义的成员函数若不包括循环等控制结构,符合内联函数要求时, C++会自动将它们作为内联函数处理(隐式inline) 。
- 也可以显式地将成员函数声明为inline。 例如
class Data//Data类定义
{int getx()//内联成员函数{return x;}inline int gety()//显式指定内联成员函数{return y;}inline void setxy(int _x, int _y);//显式指定内联成员函数void display();int x,y;
};
inline void Data::setxy(int _x,int _y)//内联成员函数
{{x=_x;y=_y;
}
void Data::display()//非内联成员函数
{...//函数体
}
- 判断成员函数是否是内联的, 有以下几条:
① 符合内联函数要求;
② 符合①的条件, 并且在类体中定义, 自动成为内联的;
③ 符合①的条件, 在类体显式指明inline, 或在外部定义时显式指明inline, 或者同时显式指明, 则函数是内联的;
④ 在类外部定义, 并且既没有在类体, 也没有在外部定义时显式指明inline, 则函数不是内联的。
3.成员函数重载及默认参数
- 可以对成员函数重载或使用默认参数。 例如:
class MAX
{int Max(int x, int y)//函数名一样,类一样,就是函数重载{}return x>y?x:y;int Max()//重载Maxreturn Max(Max(a,b),Max(c,d));int Set(int i=1,int j=1,int k=3.int l=4)//默认参数{a=i,b=i,c=k,d=l;} int a,b,c,d;
}需要注意, 声明成员函数的多个重载版本或指定成员函数的默认参数, 只能在类内部中进行。因为类定义中的声明先于成员函数的外部实现, 根据重载或默认参数函数的要求, 必须在第
1次出现函数声明或定义时就明确函数是否重载或有默认参数。先声明,再定义
4.成员函数的存储方式
用类实例化一个对象时, 系统会为每一个对象分配存储空问。 如果一个类包括了数据成员和成员函数, 则要分别为数据和函数的代码分配存储空间。
通常, C++会为每个对象的数据成员分配各自独立的存储空间, 像结构体成员那样
那么在类中的成员函数是否会如图所示那样也分配各自独立的存储空间呢?
由于不论调用哪一个对象的函数代码, 实际调用的都是同样内容的代码。 因此, 若像上图那样存放相同代码的多份副本, 既浪费空间又无必要。
实际上, 成员函数代码只有公用的一段存储空间, 调用不同对象的成员函数时都是执行同一段函数代码。
类的数据成员与类的成员函数的关系:
成员函数从属于类;
从存储空间来说,成员函数与类是不依赖的,即:类的数据成员和成员函数是分开来存储的;例如定义了一个类
class Time//Time类
{int h,m,s;//数据成员void settime(int a,int b,int c)//成员函数{h=a.m=b,s=c;}
};sizeof(Time)的值是12。 显然, Time类的存储空间长度只取决于数据成员h、 m、 s所占的空间,
而与成员函数settime无关。 C++把成员函数的代码存储在对象空间之外的地方。
5.类的声明
- 一旦遇到类体后面的右大括号, 类的定义就结束了。
- 在一个给定的源文件中, 一个类只能被定义一次。
- 通常将类的定义放在头文件中, 这样可以保证在每个使用该类的文件都以同样的方式定义类
- 可以只声明一个类而不定义它:
class Point; //Point类声明, 非Point类定义, 因为没有类体
这个声明, 称为前向声明(forward declaration) , 表示在程序中引入了Point类类型。
在声明之后、 定义之前, 类Point是一个不完全类型, 即已知Point是一个类, 但不知道它包含哪些成员。 因此不能定义该类型的对象,只能用于定义指向该类型的指针及引用, 或者用于声明(而不是定义) 使用该类型作为形参类型或返回类型的函数。
在创建类的对象之前, 必须完整地定义该类。 这样, 编译器就会给类的对象准备相应的存储空间。
同样地, 在使用引用或指针访问类的成员之前, 必须己经定义类。
类不能具有自身类型的数据成员。 然而, 只要类名一经出现就可以认为该类己声明。 因此, 类的数据成员可以是指向自身类型的指针或引用
eg:
class Point; //Point类声明, 非Point类定义, 因为没有类体
class Line {Point a; //错误, 不能使用仅有类声明而没有类定义的类定义数据对象Point *pp, &rp; //正确, 只有类声明, 即可用它定义该类的指针或引用Line b; //错误, 类不能具有自身类型的数据成员Line *pl, &rl; //正确, 类可以有指向自身类型的指针或引用的数据成员
};
(25.2)类的定义之类的数据成员,类的成员函数,类的声明相关推荐
- 将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中
将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中 写这种.h和.cpp文件分开的大程序,虽然对很多人来说很简单,对自己来说算是第一次吧,好好学C++,加油~ 题目:定义Point类,由 ...
- javaSE-day04--ArrayList基本用方法、类内定义方法和方法重载、静态方法static(类的方法)、工具方法(static)的定义和使用
ArrayList基本用方法 package day04;import java.util.ArrayList;public class ArrayListDemo {public static vo ...
- 3-1:类与对象入门——类的引入和类的定义以及访问限定符和封装还有对面向对象的理解
文章目录 一:面向对象与面向过程 二:类的引入 三:类的定义 (1)C++类的定义 (2)类的两种定义方式 A:声明和定义全部放在类体中 B:定义和声明分开放 四:类的访问限定符及封装 (1)访问限定 ...
- c++ 类的定义与使用
类的定义: c++中类以关键字 class 开头,后跟类的名称.类的主体是包含在一对花括号中.类定义后必须跟着一个分号. 类的语法: 类有关键字class + 类名 + 中括号; 类的调用: c++ ...
- pytorch教程之nn.Module类详解——使用Module类来自定义模型
pytorch教程之nn.Module类详解--使用Module类来自定义模型_MIss-Y的博客-CSDN博客_nn是什么意思前言:pytorch中对于一般的序列模型,直接使用torch.nn.Se ...
- 【SQLAlchemy】第2节:模型类的定义与创建
[SQLAlchemy]第2节:模型类的定义与创建 1. 导包并创建Base类 2. 定义Class类 3. 创建模型类(在数据库中生成这个User表) 3.1 创建连接引擎 3.2 创建(第1种方法 ...
- python为什么要实例化对象_python:类的定义、实例化对象
定义:类的定义使用关键字 ,class 关键字: 封装:类可以把各种对象组织在一起,作为类的属性,通过 . (点)运算符来调用类中封装好的对象 属性:变量在类中称为属性,但是类中的属性不仅仅只包含变量 ...
- 为什么static成员的类型可以是类本身?又为什么非static成员被限定声明为其自身类对象的指针或引用?...
看到<C++ Primer>中的一句话,才想起分析一下这个问题:"static 数据成员的类型可以是该成员所属的类类型.非 static 成员被限定声明为其自身类对象的指针或引用 ...
- Python的面向对象,魔术方法、类的三大特征、自省、实例空间、经典类与新式类
目录 1.什么是面向对象 1.1 面向过程 1.2 面向对象 1.3 面向对象的优点 2.类 2.1 什么是类.对象,方法和属性 2.2 类的定义和使用 2.2.1 类名规范和类的写法 2.3 魔术方 ...
最新文章
- python 把字母转数字
- return 关键字 c
- C语言拼接字符串 -- 使用strcat()函数
- net core体系-web应用程序-4asp.net core2.0 项目实战(1)-11项目日志解决方案
- wxpython实例源码_wxpython中复选框的基本使用源码实例
- 经理和下属谁更需要去了解业务
- c/c++教程 - 1.6 程序流程结构 if switch do while for break continue goto ?:三目运算符
- 如何用一段代码证明JVM加载类是懒加载模式?分享PDF高清版
- AutoWare 使用
- python 学习第十二课
- Hadoop (一) Hadoop学习
- 使用tftp服务把路由器的配置上传到服务器
- Android:JNI 与 NDK到底是什么?(含实例教学)
- html打印26个字母,用js完成:输出26个英文字母任意3个字母的全部组合
- https防止注入_离子注入新法,将钢的耐磨性提高百倍
- 开发一款APP需要准备哪些资料
- 诺丁汉大学计算机专业介绍,诺丁汉大学计算机科学本科专业.pdf
- 清华“差生”10年奋斗经历,只写事业,不写女人
- NoSQL 数据库有哪些典型应用?
- Pandas大量Excel数据写入Mysql