Monday, July 9, 2007

FW: Generic Programming- common technique.

 

         class _Tr = char_traits<_E>

template<class _E,
 class _Tr = char_traits<_E>,
 class _A = allocator<_E> >
 class basic_string {}

 

         Operator overload

 

_Myt& operator=(const _Myt& _X){}

_Myt& operator+=(const _Myt& _X){}

 

 

          Typename

 

template<class _Iter>

            struct iterator_traits

            {          // get traits from iterator _Iter

            typedef typename _Iter::iterator_category iterator_category;

            typedef typename _Iter::value_type value_type;

            typedef typename _Iter::difference_type difference_type;

            typedef difference_type distance_type;    // retained

            typedef typename _Iter::pointer pointer;

            typedef typename _Iter::reference reference;

            };

 

 

         Marco

_STD_BEGIN    

_STD_END

 

 

         Nested class.

class _CRTIMP ios_base {

            class failure : public runtime_error { … };

            … …

};

 

 

         Explicit

           

explicit basic_ios(_Mysb *_S)

 

explicit

 

c++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢? 如果c++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示: class MyClass { public: MyClass( int num ); } .... MyClass obj = 10; //ok,convert int to MyClass 在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作: MyClass temp(10); MyClass obj = temp; 上面的所有的操作即是所谓的"隐式转换" 如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显示",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显示的,那么下面的代码就不能够编译通过了,如下所示: class MyClass { public: explicit MyClass( int num ); } .... ...

 

C++中有两种"用户定义的型别转换":型别转换操作符和单参数构造函数。

explicit
就是用来禁止"单参数构造函数"的型别转换功能的。

 

 

         inline

inline ios_base& __cdecl boolalpha(ios_base& _I)

            {_I.setf(ios_base::boolalpha);

            return (_I); }

 

 

         exception, failure, allocator, scentry

 

         Using

Class MyRegOpen{

using std::nothrow;

}

命名空间(Namespace

STL相关的概念是命名空间(namespace)。STL定义在std命名空间中。有3种方法声明使用的命名空间:

1.用using关键字使用这个命名空间,在文件的顶部,但在声明的头文件下面加入:
using namespace std;
这对单个工程来说是最简单也是最好的方法,这个方法可以把你的代码限定在std命名空间中。

2.使用每一个模板前对每一个要使用的对象进行声明(就像原形化):
using std::cout;
using std::endl;
using std::flush;
using std::set;
using std::inserter;
尽管这样写有些冗长,但可以对记忆使用的函数比较有利,并且你可以容易地声明并使用其他命名空间中的成员。

3.在每一次使用std命名空间中的模版时,使用std域标识符。比如:
typedef std::vector VEC_STR;
这种方法虽然写起来比较冗长,但是是在混合使用多个命名空间时的最好方法。一些STL的狂热者一直使用这种方法,并且把不使用这种方法的人视为异类。一些人会通过这种方法建立一些宏来简化问题。

除此之外,你可以把using namespace std加入到任何域中,比如可以加入到函数的头部或一个控制循环体中。

 

         Typename

         c++Template中很多地方都用到了typenameclass这两个关键字,而且好像可以替换,是不是这两个关键字完全一样呢?
相信学习C++的人对class这个关键字都非常明白,class用于定义类,在模板引入c++后,最初定义模板的方法为: template<class T>......

这里class关键字表明T是一个类型,后来为了避免class在这两个地方的使用可能给人带来混淆,所以引入了typename这个关键字,它的作用同
class
一样表明后面的符号为一个类型,这样在定义模板的时候就可以使用下面的方式了: template<typename
T>......
在模板定义语法中关键字classtypename的作用完全一样。
typename
难道仅仅在模板定义中起作用吗?其实不是这样,typename另外一个作用为:使用嵌套依赖类型(nested depended name),如下所示:

         class MyArray
{
public
typedef int LengthType;
.....
}

template<class T>
void MyMethod( T myarr )
{
typedef typename T::LengthType LengthType;
LengthType length = myarr.GetLength;
}

        
这个时候typename的作用就是告诉c++编译器,typename后面的字符串为一个类型名称,而不是成员函数或者成员变量,这个时候如果前面没有
typename
,编译器没有任何办法知道T::LengthType是一个类型还是一个成员名称(静态数据成员或者静态函数),所以编译不能够通过。

 

Question:

 

1.     extern template class _CRTIMP basic_ios<char, char_traits<char> >;  ??

 

2.     why static?

Struct char_traits{

static void __cdecl assign(_E& _X, const _E& _Y);

}

 

3.     s

 

 

 

 

 

 

No comments: