C++面向对象编程(下)

C++面向对象编程下

转换函数

转换函数分为两类:将本类型转换为其它类型和将其他类型转换为本类型

将本类型转换为其它类型

定义操作符类型名()即可将本类型转换为其它类型的函数,如下:

class Fraction {
public:
	Fraction(int num, int den = 1):
		m_numerator(num), m_denominator(den){}
	operator double() const {
		return (double)(m_numerator * 1.0 / m_denominator);
	}      	    
private:
	int m_numerator;     //分子
	int m_denominator;  //分母
};

这种类型转换有可能是隐式的,如下所示:

Fraction f(3, 5);
double d = f + 4;  //隐式转换,调用Fraction::operator double()函数将f转换为double类型变量

对于f + 4这条语句,编译器可能会去寻找以下重载了运算符+的两个函数:
1.Fraction::operator +(double)
2.operator+(Fraction, double)
若这两个函数都没有找到,编译器就去寻找能否将Fraction类型转换为double类型,找到了Fraction::operator double(),发生了隐式转换。

在上面的例子中,如果定义了重载运算符+的函数,就不会再发生隐式转换。

class Fraction {
public:
	Fraction(int num, int den = 1):
		m_numerator(num), m_denominator(den){}
	explicit operator double() const {
		return (double)(m_numerator * 1.0 / m_denominator);
	}      
	double operator +(double d) const {
		return (double)(m_numerator * 1.0 / m_denominator) + d;
	}
private:
	int m_numerator;     //分子
	int m_denominator;  //分母
};

Fraction f(3, 5);
double d = f + 4;  //直接调用Fraction::operator+(double),不发生类型转换

将其他类型转换为本类型

类似的,也有可能通过隐式调用构造函数将其他类型转换为本类型,如下:

class Fraction {
public:
	Fraction(int num, int den = 1):
		m_numerator(num), m_denominator(den){}
	Fraction operator +(const Fraction& d) const {  //重载运算符
		return Fraction(m_numerator + d.m_numerator, m_denominator + d.m_denominator);	
	}
private:
	int m_numerator;     //分子
	int m_denominator;  //分母
};

Fraction f(3, 5);
Fraction d = f + 4;  //调用Fraction类构造函数将4转换为Fraction类型变量

在上面的例子中,编译器找不到函数Fraction::operator+(int),就退而求其次,先隐式调用Fraction类的构造函数将4转换为Fraction类型变量,在调用Fraction::operator+(Fraction)函数实现+运算

使用explicit关键字避免隐式转换

class Fraction {
public:
	explicit Fraction(int num, int den = 1):
		m_numerator(num), m_denominator(den){}
	explicit operator double() const {
		return (double)(m_numerator * 1.0 / m_denominator);
	}
private:
	int m_numerator;     //分子
	int m_denominator;  //分母
};

  Fraction f(3, 5);
  Fraction d = f + 4;  //编译不通过,没有匹配的“+”运算符 
  double d = f + 4;   //编译不通过,没有匹配的“+”运算符 

使用explicit关键字修饰函数以后,上述类型的隐式转换将不会发生

伪指针(pointer-like classes)和伪函数(function-like classes)

伪指针

伪指针是指作用类似于指针的对象,实现方式是重载*->运算符。标准库中的shared_ptr类是一个典型的伪指针类,代码如下:

template<class T>
class share_ptr {
public:
	T& operator*() const {
		return *px;
	}
	T* operator->() const {
		return px;
	}
	//...
private:
	T* px;
	//...
};

标准库的迭代器_List_iterator也是一个伪指针类,代码:
在这里插入图片描述
除了重载了*->运算符之外,还重载了原生指针的其他运算符

伪函数

伪函数是指作用类似于函数的对象,实现的方法是重载()运算符,在标准库中也有一些应用:

template<class T>
struct identity{
	const T&;
	operator()(const T& x)const {
		return x;
	}
};

template<class Pair>
struct select1st{
	const typename Pair::first_type&
		operator()(const Pair& x) const { return x.first };
};

template<class Pair>
struct select2nd {
	const typename Pair::second_type&
		operator()(const Pair& x) const { return x.second; };
};

模板

类模板、函数模板和成员模板

类模板实例化需要指定具体类型:

template<typename T>
class complex {
public:
	complex(T r = 0, T i = 0)
		: re(r), im(i) {}

	complex& operator+=(const ccomplex&);
	T real() { return re; }
	T imag() { return im; }
private:
	T re, im;
};

complex<double> c1(2.5, 1.5);
complex<int> c2(1, 2);

函数模板在编译的时候会进行参数推导,因此不需要指定具体类型

template<class T>
inline const T& min(const T& a, const T& b) {
	return b < a ? b : a;
}
	min(3, 2);
	min(complex(2, 3), complex(1, 5));

成员模板用于指定成员函数的参数类型:

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值