重载总结

下述内容,均从C++ primer进行摘录总结:

一)重载的定义:

    如果同一个作用域内的几个函数名字相同但形参列表不同。
提示:main函数不能进行重载
void print(const int ia[], size_t size);     //两个重载函数
void print(const int *beg, const int *end); 
二)重载和const形参
    我们通过 底层const进行函数重载
//合法的,区别是他们的引用类型的形参是否引用了常量,属于底层const
int  calc(char, char);
int  calc(const char&, char const&);

//合法的,区别是他们的指针类型的形参是否指向了常量,属于底层const
int  calc(char*, char*);
int  calc(char const*, char const*);

//非法的重载:两个函数的区别是他们形参本身(指针类型)是否为常量
//属于顶层const,属于精确匹配范畴:向实参添加顶层const或者从实参中删除顶层const
int  calc(char a, char b);
int  calc(char* const, char* const);
注意:我们可以通过 const_cast进行const重载,有效避免重复代码的产生
int  calc(char* s1, char* s2)
{
	return calc(const_cast<char const*>(s1), const_case<char const*>(s2));
}
三)重载与引用
   ①我们可以通过改变参数的左值引用和右值引用进行重载,如下所示
class StrVec{
public:
	void push_back(const std::string&);	//拷贝元素
	void push_back(std::string&&);		//移动元素
};
②我们可以通过引用限定符来区分重载函数
class Foo{
	friend Foo &retFoo();		//返回一个引用
	friend Foo retVal();        //返回一个右值
public:
	Foo sorted() &&;			//可用于可改变的右值
	Foo sorted() const &;		//可用于任何类型的Foo,注意&不能省
	
	//此外引用限定符的另一个作用:只能向可修改的左值赋值
	Foo& operator=(const Foo&) &; 
	//Foo j;
	//retFoo() = j; //正确
	//retVal() = j; //错误,retVal返回一个右值
private:
	vector<int> data;
};

//本对象为右值(对象状态可改变),因此可以进行原址排序
Foo Foo::sorted()&&{
	sort(data.begin(), data.end());
	return *this;
}
	
//被对象是const或一个左值,那种情况我们都不能对原址排序
Foo Foo::sorted() const &{
	Foo ret(*this);
	sort(ret.data.begin(), ret.data.end());
	return ret;
}

//通过调用对象时左值还是右值决定调用哪一个
retFoo.sorted();    //左值,调用Foo Foo::sorted() const &
retVal.sorted();	//右值,调用Foo Foo::sorted()&&
四)重载与模板
  ①通过显示模板参数消除函数调用指针的歧义;
 //定义一个函数模板
 template <typename T> int compare(const T &v1, const T &v2);
 
//定义重载函数
void func(int (*)(const string&, const string&);
void func(int (*)(const int& , const int&);
func(compare);       //错误,使用compare的那个实力
func(compare<int>);  //正确,显示指示实例化那个版本
②当有多个重载模板对一个调用提供同样好的匹配时,应选择最特例化的一个;
//由于为const T&,本质上可以接受任意类型(特例化为左值或const右值)
//注意(T&&也可接受任意类型,特例为非const右值)
template <typename T> std::string debug_rep(const T &t);

//该模板主要针对指针类型
template <typename T> std::string debug_rep(T *p);

//考虑下面的调用那个
string s("hello"); 
const string *sp = &s; 
cout<< debug_rep(sp) << endl;  //选择template <typename T> std::string debug_rep(T *p),该目标更特例
③对于一个调用,如果一个非函数模板与一个函数模块提供同样好的匹配时,选择非模板版本;
//模板
template <typename T> std::string debug_rep(const T &t);

//普通函数
std::string debug_rep(const std::string &s);
 
//考虑下面调用
string s("hi");
cout<< debug_rep(s)<<endl;  //选择普通函数进行调用
④模板特例化的本质是实例化一个模板,而非重载它。因此,特例化不影响匹配;
#include <iostream>
using std::cout; using std::endl;

#include <functional>
using std::less;

#include <cstring>
using std::strcmp;

// version of compare that will be correct even if used on pointers
template <typename T> int compare(const T &v1, const T &v2)
{
	cout << "compare(T)" << "\t";

	if (less<T>()(v1, v2)) return -1;
	if (less<T>()(v2, v1)) return 1;

	return 0;
}

template<unsigned N, unsigned M> 
int compare(const char (&p1)[N], const char (&p2)[M])
{
	cout << "compare(const char arrays)" << "\t";

	return strcmp(p1, p2);
}

template<> 
int compare(const char *const& p1, const char *const& p2)
{
	cout << "compare(const char*const)" << "\t";

	return strcmp(p1, p2);
}

int main()
{
	int *p1 = new int(45);
	int *p2 = new int(42);

	// because we're comparing pointer values, the result of
    // this call may vary each time the program is run
	cout << compare(*p1, *p2) << endl;   //调用template <typename T> int compare(const T &v1, const T &v2) 
	cout << compare(p1, p2) << endl;     //调用template <typename T> int compare(const T &v1, const T &v2) 

	cout << strcmp("hi", "mom") << endl;    
	cout << compare("hi", "mom") << endl; //字面值常量字符串,调用template<unsigned N, unsigned M> 
										  //int compare(const char (&p1)[N], const char (&p2)[M]) 

	const char *cp1 = "hi", *cp2= "mom";  // 
	cout << compare(cp1, cp2) << endl;    //调用其特例化版本,
										  //template<> int compare(const char *const& p1, const char *const& p2) 
	return 0;
}
 
//打印结果
compare(T)      1
compare(T)      -1
-1
compare(const char arrays)      -1
compare(const char*const)       -1

--------------------------------
Process exited after 0.02734 seconds with return value 0
请按任意键继续. . .









  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值