第9章 关于对象的高级专题

    第8章中介绍了C++中面向对象编程的基本概念,讨论了类的定义和实现、对象的创建和组织、特殊数据成员和函数成员的用法等,本章将在前文介绍的基础上,探讨关于对象的一些深层次内容。

    本章主要涉及以下知识点。

    ❑类的作用域:介绍类的作用域的概念。

    ❑类的作用域和可见域:介绍类的作用域和可见域的相关知识。

    ❑对象的生存期、作用和可见域:介绍类对象实例化及释放等相关内容。

    ❑友元:介绍友元的概念、其与成员和非成员函数的关系,如何重载及友元类。

    ❑运算符重载:介绍如何进行运算符的重载及其各种形式。

    ❑运算符示例:介绍常用的几种运算符如何重载。

    ❑类型转换:介绍其他类型和自定义类型之间的转换。

    ❑重载函数:介绍如何选择重载函数。

    9.1 类的作用域

    第6章已经介绍了作用域和可见域的概念,知道可见域包含于作用域中,了解了局部作用域和全局作用域,本节讨论的是与类相关的作用域,大体分为类作用域、类名的作用域以及对象的作用域3部分内容。

    在类中定义的数据成员和函数成员的作用域是整个类,这些名称只有在类中(包含类的定义部分和类外函数的实现部分)是可见的,在类外是不可见的,因此,可以在不同类中使用相同的成员名。另外,类作用域意味着不能从外部直接访问类的任何成员,即使该成员的访问权限是public,也要通过对象名来调用,对于static成员,要指定类名来调用。

    如果发生“屏蔽”现象,类成员的可见域将小于作用域,但此时可借助this指针或“类名:”形式指明所访问的是类成员,这有些类似于使用“:”访问全局变量。如示例代码9.1所示。

    代码9.1 数据成员、形参和全局变量VariableAccess


    <———————————文件名:example901.cpp————————————————> 01 #include<iostream> 02 using namespace std; 03 extern int x=100;//定义性声明,全局int型变量x 04 extern int z=200;//定义性声明,全局int型变量z 05 class Example//Example类定义 06 { 07 int x;//默认为private的成员列表 08 int y; 09 public: 10 Example(int xp=0,int yp=0)//构造函数 11 { 12 x=xp; 13 y=yp; 14 } 15 void print(int x)//成员函数print(),形参为x 16 { 17 cout<<"传递来的参数:"<<x<<endl;//形参x覆盖掉了成员x和全局变量x 18 //此处的y指的是成员y,如果要访问成员x,可使用this指针 19 cout<<"成员x:"<<(this->x)<<",成员y:"<<y<<endl; 20 cout<<"除了this指针外,还可以使用类名:的形式:"<<endl; 21 //或使用类名加作用域限定符的形式指明要访问成员x 22 cout<<"成员x:"<<Example:x<<",成员y:"<<y<<endl; 23 cout<<"全局x:"<<(:x)<<endl;//访问全局变量x 24 //没有形参、数据成员对全局变量z构成屏蔽,直接访问z即可 25 cout<<"全局z:"<<z<<endl; 26 } 27 }; 28 29 int main() 30 { 31 Example ex1;//声明一个Example类的对象ex1 32 ex1. print(5);//调用成员函数print() 33 return 0; 34 }

    输出结果如下所示。


    传递来的参数:5 成员x:0,成员y:0 除了this指针外,还可以使用类名:的形式。 成员x:0,成员y:0 全局x:100 全局z:200

    【代码解析】在Example类中,其中的数据成员和函数成员都具有类作用域,对成员x和y来说,如果没有“屏蔽”,x和y的可见域等于其作用域,可以在类定义和类实现的任何地方使用x和y来访问数据成员,在代码第17行,由于在print函数中,形参x屏蔽了类的数据成员x,此时数据成员x在print函数内不可见,如何在print函数中访问类的数据成员x呢?有两种途径:一是使用“类名:数据成员名”,二是使用this指针。

    注意

    从代码9.1可以看到,在print函数内,数据成员y并没有被屏蔽,因此使用y可以直接访问类的数据成员y。

    从另一种意义上说,数据成员x在整个类内屏蔽了全局变量x,此时,使用“:x”可以在程序的任何地方访问全局变量,当然,如果类中没有和全局变量同名的数据成员,全局变量在类中便是可见的,如代码9.1中的z。

    注意

    类内的成员函数同样可能屏蔽外部的全局函数,如果要在类内调用外部的全局函数,仍然可以使用“:全局函数名”的形式。