GeekBand 随笔分享(四)
//----------------------------------------------------对象模型 -------------------------------------------------------------------------
一、conversion function:
用转换构造函数可以将一个指定类型的数据转换为类的对象。但是不能反过来将一个类的对象转换为一个其他类型的数据(例如将一个Complex类对象转换成double类型数据)。
C++提供类型转换函数(type conversion function)来解决这个问题。类型转换函数的作用是将一个类的对象转换成另一类型的数据。如果已声明了一个Complex类,可以在Complex类中这样定义类型转换函数:
operator double( )
{
return real;
}
operator double( )
{
return real;
}
class Fraction{
public:
Fraction(int num,int len = 1):m_nummerator,m_denominator(len){}
operator double()const{
return(double)(m_nummerator/m_denominator);
}
private:
int m_nummerator;
int m_denominator;
};
Fraction f(3,5);
double d = 4+f;//have error
二、non-explicit-one -argument ctor:
class Fraction{
public:
Fraction(int num,int len = 1):m_nummerator,m_denominator(len){}
Fraction operator +(const Fraction&f){
return Fraction(...);
}
private:
int m_nummerator;
int m_denominator;
};
Fraction f(3,5);
double d = 4+f;//调用non-explicit ctor 将4转为
Fraction (4,1),然后再调用operator+三、conversion function vs.non-explicit-one-argument ctor:
class Fraction{
public:
Fraction(int num,int len = 1):m_nummerator,m_denominator(len){}
operator double()const{
return(double)(m_nummerator/m_denominator);
Fraction operator +(const Fraction&f){
return Fraction(...);
}
private:
int m_nummerator;
int m_denominator;
};
Fraction f(3,5);
double d2 = 4+f;//[error]ambiguous 因为有歧义,编译器不知走哪一条路线好
四、explicit-one-argument ctor:
explict 很少应用到,主要应用场合: 构造函数。C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。
class Fraction{
public:
explict Fraction(int num,int len = 1):m_nummerator,m_denominator(len){} //多了explict 关键字
operator double()const{
return(double)(m_nummerator/m_denominator);
Fraction operator +(const Fraction&f){
return Fraction(...);
}
private:
int m_nummerator;
int m_denominator;
};
Fraction f(3,5);
double d2 = 4+f;//[error]conversion from 'double' to 'fraction' requestion,因为4没有办法变成4/1
五、pointer-like classes:
1》》第一大类:智能指针
templated<class T>
class shared_ptr
{
public:
T& operator*() const {return *px;}
T& operator->() const {return px;}
shared_ptr(T* p):px(p){}
private:
T* px;
long* pn;
}
//------------
struct Foo
{
...
void method(void){...};
}
shared_ptr<Foo> sp(new,Foo);
Foo f(*sp);
sp ->method(); //
箭头符号有一个特点,就是作用下去,还会继续下去,还会等于 px ->method();px ->method();
2》》第二大类:迭代器:
迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器不仅仅是指针,因此你不能认为他们一定具有地址值。例如,一个数组索引,也可以认为是一种迭代器。
T& operator*() const {return *px;}
T& operator->() const {return px;}
比如:
对于STL数据结构和算法,你可以使用五种迭代器。下面简要说明了这五种类型:
- · Input iterators 提供对数据的只读访问。
- · Output iterators 提供对数据的只写访问
- · Forward iterators 提供读写操作,并能向前推进迭代器。
- · Bidirectional iterators提供读写操作,并能向前和向后操作。
- · Random access iterators提供读写操作,并能在数据中随机移动。
六、function-like classes, 所谓仿函数
template<class T>
struct identity xxxxx {
const T&
operator()(const T& x)const{return x;}
};
template <class Pair>
struct selectlst xxxxx{
const typename Pair::first_type&
operator()(const Pairt& x)const
{return x.first;}
}
七、namespace 经验谈
using namespace std;
//----------------------------------
#include <iostream>
#include <memory>
namespace jj01
{
......
}//namespace
//---------------------------------
#include <iostream>
#include <list>
namespace jj02
{
......
}//namespace
八、class template
定义类模板的一般形式是:
template <类型名 参数名1,类型名参数名2,…>
class 类名
{
类声明体
};
例如,template <class T>
class Smemory
{…
public:
void mput(T x);
…
}
template <类型名 参数名1,类型名参数名2,…>
class 类名
{
类声明体
};
例如,template <class T>
class Smemory
{…
public:
void mput(T x);
…
}
九、function template
template
Type min( Type (&arr) [size] );
十、Member Template
可以这么理解:类是一个模版,里面的成员函数也是有模版。这样的好处为,外面的类T1改变时,里面的U1也是可以改变的。
template <class T1,class T2>
struct pair{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pairt():first(T1(),second(T2)()){}
template <class U1,class U2>
pair(const pair<U1,U2>&P):first(p.first),second(p.second){}
}
十一、specialization 模版特化
模版分:泛化(也称全泛化)
特化(与全泛化相对应)
十二、模板偏特化
分两种:
1、个数的偏:
2、范围的偏:
十三、template template parameter模板模板参数(很高升的一个主题了
//------------------------------C++标准库
1、迭代器
2、容器
3、算法
4、仿函数
//--------------------------- 三大主题
1.variadic templates(since)
2.
auto (since c++11)
eg:
list<string> c;
...
auto ite = find(c.begin(),c.end(),targat);
如果写成下面这样,就有问题,因为编译哭推不出ite是哪个类型
auto ite;
ite = find(c.begin(),c.end(),targat);
3.
ranged-base for(sincec++11)
for(decl:coll){ //coll 这里其实是个容器
statemant
}
eg:
for(int i:{2,3,4,5}){
cout << i<<endl;
}
//---------------------------------reference 专题
知识点一:
应该这样表达才准确,也好理解!
reference 其实实际上就是个指针,他的大小就是pointer大小,但它会产生一种假象,大小与它代表的变量相同,可以用sizeof看出,这是编译器故意这么做的。
reference 一定要在创建时就初始化。
知识点二:
c++ 函数signature问题