依然是温故而知新,不过现在更多的是以此为乐的心态啦。本篇通过代码实例,展示c++函数重载相关知识,包括构造函数的重载、操作符重载等。
在构造函数重载中,给大家带来点稍微提升的用法, 看了不吃亏,看了不上当
鞭策下面的代码吧,以后在某些场景上SHOW一把时,你可能用的上。
#include <iostream>
#include <assert.h>
#include <sal.h>
#include <string>
#include <vector>
using namespace std;
知识点
do{ statement; }while(0) 经常用在宏定义中,减少一些错误的发生
//
#ifdef MYTRACE()
#else
#define MYTRACE() do { std::cout << __FUNCTION__ << ",line" << __LINE__ << std::endl;}while(0)
#endif
class Student
{
public:
/// construct
Student(){MYTRACE();}
Student( _In_ const std::string name):m_name(name){MYTRACE();}
Student(const std::string name,const int age):m_name(name),m_age(age){MYTRACE();}
/// copy construct
Student( _In_ const Student& that){
this->m_age = that.m_age;
this->m_name = that.m_name;
MYTRACE();
}
/// 拷贝赋值
Student& operator=(const Student& that){
if(this == &that){
return *this;
}
this->m_age = that.m_age;
this->m_name = that.m_name;
return *this;
}
/// 操作符重载
friend ostream& operator <<(ostream& out,const Student& that){
return out << that.m_name << " is " << that.m_age << " years old.";
}
bool operator !=(const Student& that){
return !(that.age() == this->m_age && that.name() == this->m_name);
}
bool operator ==(const Student& that){
return that.age() == this->m_age && that.name() == this->m_name;
}
/// 常成员函数
const int age() const { return m_age;}
const std::string name() const { return m_name;}
private:
int m_age = 0;
std::string m_name;
};
Student
中我们使用了C++中的一些基础知识,只能说中规中矩,平平无奇。
class StudentList
{
public:
/*********************construct*******************/
StudentList(){}
StudentList(std::vector<Student> l):m_sl(l){}
StudentList(const Student& t){ m_sl.push_back(t); }
StudentList(const Student&& t){ m_sl.push_back(t); }
/// 禁用拷贝构造和拷贝赋值
StudentList(const StudentList& that) = delete;
void operator =(const StudentList& that) = delete;
/// 玩点儿高级的:参数列表构造
void append(const Student& t){ m_sl.push_back(t); }
template <typename ...Args>
void append(const Student& t, const Args&... args) {
m_sl.push_back(t);
append(args...); // 递归
}
template <typename ...Args>
StudentList(const Student& t,const Args&... args){ append(t,args...);}
/// 流式构造
StudentList& operator<<(const Student& t) { append(t); return *this; }
/*********************construct*******************/
const std::vector<Student>& data() const{return m_sl;}
/******************************* 操作符重载 ************************/
friend ostream& operator <<(ostream& out,const StudentList& that){
for (const auto& v : that.data()) { out << "(" << v.name() << "," << v.age() << ")" ; }
return out;
}
const Student& operator []( _In_ const unsigned& index)const {
assert(index < m_sl.size());
return m_sl[index];
}
const Student& at(_In_ const unsigned& index) const { return m_sl[index];}
bool operator !=(const StudentList& that)
{
if(this == &that){return false;}
if(this->data().size() == that.data().size())
{
for(unsigned i = 0; i < that.data().size();++i){
if( const_cast<Student&>(this->data()[i])
!= const_cast<Student&>(that.data()[i])){
return true;
}
}
}
return true;
}
bool operator ==(const StudentList& that){
return !(const_cast<StudentList&>(that) != const_cast<StudentList&>(*this));
}
/// 这里不做去重处理
StudentList& operator +=(const StudentList& that)
{
for(auto v : that.data()){
append(v);
}
return *this;
}
/******************************* 操作符重载 ************************/
private:
std::vector<Student> m_sl;
};
StudentList
类中我们做了一些有意思的尝试,譬如让StudentList
支持参数列表的初始化,这让他看起来显然cool了一些,其次我们通过重载 operator <<
操作符,增加了支持流式的操作。这类似Qt中的
QStringList() << "wo" << "miss" << "u";
是不是瞬间高大上了一些呢。有点像写文章时堆砌的华丽辞藻?显然不是,一些高级语法的应用,其实只是为了让我们的程序更加优雅,更健壮~
int main()
{
/// 测试重载的Student构造函数
Student st1;
Student st2("LiLei",25);
Student st3("Keke",26);
/// 测试拷贝构造函数
Student st4(st3);
std::cout << st4 << std::endl;
st4 = st2;
std::cout << st4 << std::endl;
/// list类型参数 构造函数
StudentList sl(std::vector<Student>{st2,st3,st4});
std::cout << sl << std::endl;
/// 参数列表 递归构造函数
StudentList sl1{st2,st3,st4,Student("zhanglu",24)};
std::cout << sl1 << std::endl;
/// 流式构造
StudentList sl2;
sl2 << st2 << st3 << st4 << Student("zhaoya",25) << Student("lixiu",25);
std::cout << sl2 << std::endl;
// 测试使用下标重载函数
std::cout << sl2[1] << std::endl;
std::cout << sl2.at(0) << " " << sl2.at(1) << std::endl;
// std::cout << sl2[6] << std::endl; // error
// 测试 != 和 == 操作符
std::string sflag = (sl2 != sl2) ? "true" : "false";
std::cout << sflag << std::endl;
sflag = (sl2 == sl2) ? "true" : "false";
std::cout << sflag << std::endl;
sflag = (sl2 != sl1) ? "true" : "false";
std::cout << sflag << std::endl;
// 测试 "+" 操作符
StudentList sl3{Student("xiaoli",25)};
sl3 += sl2;
std::cout << sl3 << std::endl;
return 0;
}
ok,有兴趣你也动手试试吧~
每日几行代码 + 一瓶劲酒,祝吾早日登(升)天