第四周
勿在浮沙筑高台
C++11
类的合理转换函数,将类转为相应类型
不用写返回值
class Fraction
{
public:
Fraction(int num,int den=1):m_numerator(num),m_denominator(den){}
operator double() const{return (double)(m_number/m_denominator);
Private:
int m_numerator;//分子
int m_denominator;//分母
};
Fraction f(3,5);
double d=4+f;//调用operator double() 将f转为0.6
non-expiation-one-argument
ctor
class Fraction
{
public:
Fraction(int num,int den = 1):m_numerator(num),m_denominator(den){}
Fraction operator+(const. Fraction& f){return Fraction(....);}
};
Franction f(3,5);
Fraction d2=f+4;//调用 non-exeplict ctor 将4转为Fraction(4,1)
//然后调用Operator+
explicit-one-argument ctor
class Fraction
{
public:
explicit Fraction(int num,int den = 1):m_numerator(num),m_denominator(den){}
operator double() const{
return (double)(m_numerator/m_denominiator);}
Fraction operator+(const. Fraction& f){return Fraction(....);}
};
Franction f(3,5);
Fraction d2=f+4;//从4转为Fraction失败了,原因是构造函数前加了explict,构造函数不会用于隐式转换
pointer-like classes,关于智能指针
迭代器就是一种智能指针。
shared_ptr是一种智能指针(smart pointer),作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。这便是所谓的引用计数(reference counting)。
template
class shared_ptr//
{
public:
T& operator* () const
{return *px;}
T& operator->() const
{return px;}
share_ptr(T* p): px(p){}
private:
T* px;
long* pn;
};
struct Foo
{
......
void method();
};
shared_ptr sp(new Foo);
Foo f(* sp);
sp->method();
//px->method();"->"作用符会自动执行下去(作用于sp上,但是可以执行px->method();)
关于迭代器
template
struct __list_node //节点结构体
{
void* prev;
void* next;
T data;
}
struct __list_iterator
{
typedef __list_iterator self;
typedef Ptr pointer;
typedef Ref reference;
typedef __list_node* link_type; //指针
link_type node;
bool operator==(const self& x) const {return node ==x.node;}
bool operator!=(const self& x) const {return node !=x.node;}
reference operator*() const {return (*node).data;}
pointer operator->() const {return &(operator* ()); }
self& operator++() {node = (link_type)((*node).next); return *this;}
self& operator++(int) {self tmp = *this; ++*this;return tmp;)}
self& operator--() {node = (link_type)((*node).prev);return *this;}
self& operator--(int) {self tmp = *this; --*this;}
};
reference operator*() const {return (*node).data;}
poiner operator->() const {return & (operator*());} //取 data;
function-like classes ,仿函数
template
struct identity
{//重载小括号“()”,函数对象
const T& operator() (const T& x ) const {return x;}
};
template
struct select1st
{
const typename Pair::first_type& operator()(const Pair& x)const{return x.first;}
};
template
struct select2nd
{
const typename Pair::second_type& operator() (const Pair& ) const{return x.second;}
};
template
struct pair
{
T1 first;
T2 second;
pair() : first(T1()),second(T2()) {}
pair(const T1& a,const T2& b):first(a),second(b){}
};
namespace
用namespace区分测试内容,写一个测试程序即可
class template 类模板
function template 函数模板
//编译器会对function template 进行实参推导
template
inline
const T& min(const T& a,const T& b)
{
return b < a ? b:a;
}
class stone
{
public:
stone(int w,int h,int we){}
bool operator< (const stone& rhs) const{return _weight < rhs._weiget;}
private:
int _w,_h,_weight;
};
stone r1(2,3),r2(3,3),r3;
r3 = min(r1,r2);//实参推导T为stone,调用(stone::operator<)
模板在编译时编译出一个办成品,在使用时在编译一次
成员模板
member template
template
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair():first((T1()),second(T2()))
pare():(const T1& a,const T2& b):first(a),second(b){}
//本身是一个模板里的member ,但是自己又是模板
template
pair(const pair& p):first(p.first),second(p.second)
//U1和U2必须满足“first(p.first),second(p.second)”条件
}
class Base1{};
class Derived1:public Base1{};
class Base2{};
class Derived2:public Base2{};
pair p;
pair p2(p);
//T1,T2 U1,U2
pair p2(pair());
template
class shared_ptr:public __shared_ptr<_Tp>
{
...
template
explict shared_ptr(_Tp1* _p):__shared_ptr<_Tp>(_p){}
...
}
Base1* ptr = new Derived1; //up-cast
shared_ptr sptr(new Deviced1); //up-cast
specialization 模板特化
泛化和特化
template
struct hash{}
template<>
struct hash
{
size_t operator()(char x) const{return x;}
};
template<>
struct hash
{
size_t operator() (int x) const {return x;}
};
template<>
struct hash
{
size_t operatot() (long x) const {return x;}
}
//编译时直接调用long,不会在用模板
count << hash()(1000); ///第一个括号是指临时变量,第二个括号是启用重载"()"
模板特化 --个数的偏
template
class vector
{
...
}
template
class vector //绑定某个参数
{...}
模板特化 --范围的偏
template
class C
{
...
};
template
class C ///指定为指针,
{
...
};
模板模板参数
//T为模板参数,同时是第二个参数的
templateclass Container>
class XCls
{
private:
Container c;
public:
...
};
//
template
using Lst = list>;
C++标准库
C++11
三大主题
variadic template(since C++11) 数量补丁的模板参数
void print()
{
}
//...是语法一部分,参数为一个和一包
template
void print(const T& firstArg,const Type&... args)
{
cout << firstArg << endl;
print(arg...);
}
sizeof(...args) ///测试一包是多少参数
print(7.5,"hello",bitset<16>(377),42);
/*
7.5
hello
0000000101111001
42
*/
auto
//before
list c;
...
list::iterator ite;
ite = find(c.begin(),c.end(),target);
//since C++11
list c;
auto ite = find(c.begin,c.end(),target);
ranged-base for(since C++)
for(decl:coll)
{
statement
}
for(int i:{2,3,4,5,6,7,8}) ///大括号自动形成容器
{
cout << i << endl;
}
vector vec;
...
for(auto elem :vec) //传值
{
cout << elem << endl;
}
for(auto& elem : vec) ///传引用,改值
{
elem *= 3; //乘以三
}
reference
int x = 0;
int* p = &x;
int& r = x; //r代表x,一定要有初值,一直不变 (所有编译器实现引用是以指针方式处理的),大小和被代表的值相同,指针4个字节(32位)
int x2 = 5;
r = x2; //r 不能重新代表其他
const 是函数签名的一部分