重载与命名空间(学习笔记)

时间:2014.07.01

地点:基地

-----------------------------------------------------------------------------------------

命名空间对函数匹配的影响主要表现在:使用using声明或using指示能将某些函数添加到候选函数集(不同版本)中。

一、与实参相关的查找与重载

对于接受类类型实参的函数而言,其名字查找是在实参的类所在的命名空间中进行。我们将在实参类以及实参类的基类所属的命名空间中搜寻候选函数。这些命名空间中所有与被调函数同名的函数都将被添加到候选集中,即使其中某些函数在调用语句处不可见。比如:

namespace NS
{
   class Quote{/*......*/};
   void Display(const Quote&){/*......*/}
}

在命名空间NS下,我们定义了一个Quote类和Display函数,该函数接受Quote类类型的参数。

class BulkItem:public NS::Quote
{
  /*......*/
};

类BulkItem继承命名空间NS下的类Quote

int main()
{
  BulkItem book1;
  Display(book1);
  return 0;
}

在这里,我们传递给Display的实参是一个类类型BulkItem,于是调用语句的候选函数查找不仅会在调用语句所在的作用域即main()函数中查找,它还会在BulkItem已经其基类Quote所属的命名空间中查找。即在这里表现为命名空间NS中声明的函数Display(const Quote&)也将被添加到候选函数集当中。从而在这里可以正确地调用到Display函数。

-----------------------------------------------------------------------------------------

二、重载与using声明

using声明语句声明的只是一个名字,而不是一个特定的函数。比如:

using NS::print(int);  //这样会编译错误,因为using不能声明特定函数
using NS::print;       //正确,using在这里只声明一个名字

这样之后,该函数的所有版本都将被引入到当前作用域之中。

using声明语句引入的函数将重载该声明语句所属作用域中已有的其他同名函数(即只要条件符合,using声明语句引入的函数与该声明语句所在作用域中的其它同名函数会构成重载关系)。比如当using语句声明出现在局部作用域中时,则引入的名字将隐藏外层作用域的相关声明,与本作用域中的同名函数重载。但另一方面,如果using声明所在的作用域中已经有一个函数与新引入的函数同名且形参列表相同,则该using声明将引发错误。

-----------------------------------------------------------------------------------------

三、重载与using指示

using指示可将命名空间的成员提升到外层作用域中,如果命名空间的某个函数与该命名空间所属作用域的函数同名,则命名空间中函数将被添加到重载集合中。比如:

namespace  my_space
{
  extern void print(int);
  extern void print(double);
}
//接下来是一个普通的函数声明
void print(const  std::string&);
//using指示,它将把该命名空间名字提升到外层作用域,并与外层作用域同名不同参的函数重载,比如在这里using指示把名字添加到print调用的候选函数集中
using namespace myspace;
//于是现在掉用print函数时有如下候选函数版本
//myspace中的print(int)
//myspace中的print(double)
//当前域中显式声明的print(const std::string&)
void FooBar(int ival)
{
  print("Value: ");  //该句会调用全局函数的print(const string&)
  print(ival);  //调用命名空间中的print(int)
}

注意using声明与using指示的区别:

using声明仅仅是声明命名空间中存在的名字,把该命名空间中的所有该名字的函数版本或该名字变量引入到当前作用域中。而using指示时把命名空间中的所有成员都提升到外层作用域之中。而且,对于using指示而言,引入一个与已有函数函数名和形参列表全部都相同的函数时也并不会产生错误。此时,只需要指明要调用的版本是命名空间中的版本还是当前作用域的版本即可。

-----------------------------------------------------------------------------------------

四、多using指示与重载

若是存在多个using指示,则来自每个命名空间的名字都会成为候选函数集的一部分。比如:

namespace SpaceOne
{
  int print(int);
}
namespace SpaceTwo
{
  double print(double);
}
//使用using指示从不同的命名空间中创建一个重载函数集合
using namespace SpaceOne;
using namespace SpaceTwo;
//还在当前域中定义一个同名不同参函数
long double print(long double);
int main()
{
  print(1);     //调用SpaceOne中的print(int)
print(2.1);  //调用SpaceTwo中的print(double)
return 0;
}

在上面,全局作用域中,函数print的重载集合中包括print(int),print(double)和print(long double),尽管它们的声明位于不同作用域中,但他们都属于mian函数中print调用的候选函数集。

重载与命名空间(学习笔记)

时间: 2024-11-10 00:52:35

重载与命名空间(学习笔记)的相关文章

C++ Primer 学习笔记_93_用于大型程序的工具 --命名空间[续2]

用于大型程序的工具 --命名空间[续2] 五.类.命名空间和作用域 名字的可见性穿过任意嵌套作用域,直到引入名字的块的末尾. 对命名空间内部使用的名字的查找遵循常规C++查找规则:当查找名字的时候,通过外围作用域外查找.对命名空间内部使用的名字而言,外围作用域可能是一个或多个嵌套的命名空间,最终以全包围的全局命名空间结束.只考虑已经在使用点之前声明的名字,而该使用仍在开放的块中: namespace A { int i; namespace B { int i; int j; int f1()

C++ Primer 学习笔记_94_用于大型程序的工具 --命名空间[续3]

用于大型程序的工具 --命名空间[续3] 六.重载与命名空间 正如我们所见,每个命名空间维持自己的作用域,因此,作为两个不同命名空间的成员的函数不能互相重载.但是,给定命名空间可以包含一组重载函数成员. 1.候选函数与命名空间 命名空间对函数匹配有两个影响.一个影响是明显的:using声明或using 指示可以将函数加到候选集合.另一个影响则微妙得多. 正如前节所见,有一个或多个类类型形参的函数的名字查找包括定义每个形参类型的命名空间.这个规则还影响怎样确定候选集合,为找候选函数而查找定义形参类

[原创]java WEB学习笔记98:Spring学习---Spring Bean配置及相关细节:如何在配置bean,Spring容器(BeanFactory,ApplicationContext),如何获取bean,属性赋值(属性注入,构造器注入),配置bean细节(字面值,包含特殊字符,引用bean,null值,集合属性list map propert),util 和p 命名空间

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

C++ Primer 学习笔记_91_用于大型程序的工具 --命名空间

用于大型程序的工具 --命名空间 引言: 在一个给定作用域中定义的每个名字在该作用域中必须是唯一的,对庞大.复杂的应用程序而言,这个要求可能难以满足.这样的应用程序的全局作用域中一般有许多名字定义.由独立开发的库构成的复杂程序更有可能遇到名字冲突 -- 同样的名字既可能在我们自己的代码中使用,也可能(更常见地)在独立供应商提供的代码中使用. 库倾向于定义许多全局名字 -- 主要是模板名.类型名或函数名.在使用来自多个供应商的库编写应用程序的时候,这些名字中有一些几乎不可避免地会发生冲突,这种名字

C++ Primer 学习笔记_64_重载操作符与转换 --转换与类类型【下】

重载操作符与转换 --转换与类类型[下] 四.重载确定和类的实参 在需要转换函数的实参时,编译器自动应用类的转换操作符或构造函数.因此,应该在函数确定期间考虑类转换操作符.函数重载确定由三步组成: 1)确定候选函数集合:这些是与被调用函数同名的函数. 2)选择可行的函数:这些是形参数目和类型与函数调用中的实参相匹配的候选函数.选择可行函数时,如果有转换操作,编译器还要确定需要哪个转换操作来匹配每个形参. 3)选择最佳匹配的函数.为了确定最佳匹配,对将实参转换为对应形参所需的类型转换进行分类.对于

初探C++运算符重载学习笔记<1>

运算符重载 含义: 对抽象数据类型也能够直接使用C++提供的运算符 对已有的运算符赋予多重的含义 使同一运算符针对不同的数据类型产生不同的行为 目的: -->扩展C++运算符的适用范围,以用于类所表示的抽象数据类型 -->程序更简洁 -->代码可读性更好 例如complex_a和complex_b是两个复数对象,如果求和,希望能直接写成 complex_a + complex_b  这样的形式. 实质: 函数重载 返回值类型 operator 运算符(参数表) { .... } 在函数编

初步C++运算符重载学习笔记<3> 增量递减运算符重载

初步C++运算符重载学习笔记<1> 初探C++运算符重载学习笔记<2> 重载为友元函数     增量.减量运算符++(--)分别有两种形式:前自增++i(自减--i).后自增i++(自减i--) 因此当我们重载该运算符时,要重载对应形式的运算符. T & operator ++() // 前自增++i T & operator ++(int) //后自增 i++ 举例: #include <iostream> using namespace std; c

C++学习笔记23,类内函数重载

该博文仅用于交流学习,请慎用于任何商业用途,本博主保留对该博文的一切权利. 博主博客:http://blog.csdn.net/qq844352155 转载请注明出处: 在一个类内,最常见的就是构造函数的重载了.这里我就不介绍了. 先来看看常见的类内重载. //method.cpp #include <iostream> #include <string> using namespace std; class base{ private: int i; string s; publ

C++ Primer 学习笔记_26_操作符重载与转换(1)--可重载/不可重载的操作符、成员函数方式重载、友元函数方式重载

C++ Primer 学习笔记_26_操作符重载与转换(1)--可重载/不可重载的操作符.成员函数方式重载.友元函数方式重载 引言: 明智地使用操作符重载可以使类类型的使用像内置类型一样直观! 一.重载的操作符名 像任何其他函数一样,操作符重载函数有一个返回值和一个形参表.形参表必须具有操作符数目相同的形参.比如赋值时二元运算,所以该操作符函数有两个参数:第一个形参对应着左操作数,第二个形参对应右操作数. 大多数操作符可以定义为成员函数或非成员函数.当操作符为成员函数时,它的第一个操作数隐式绑定