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提供了大量能使我们快速便捷地处理数据的函数和方法。