微博:
@TankyWoo基
新博客:
TankyWoo

《C++标准程序库》学习笔记2–第四章

  • 1.(P33)

Pairs(对组)的定义

class pair可以将两个值视为一个单元。map和multimap就是通过pair来管理键值/实值(key/value)的。

在pair的定义中:

namespace std { 
    template 
<class T1, class T2> 
    
struct pair { 
        
// member 
        T1 first; 
        T2 second; 
        ... 
        
// copy construct with implicit conversions 
        template <class U, class V> 
        pair(cosnt pair
<U, V> & p) 
        : first(p.first), second(p.second) { 
        } 
    }; 
    ... 
}

 

 

 

可以看到在copy构造函数时,使用了template,这是对于需要隐式转换的。如果是相同类型,则不是调用此构造函数,而是调用系统合成的copy构造函数。

对于上面代码实现的方法,在学习笔记1(http://www.wutianqi.com/?p=2025)中第二点讲到过。

 

  • 2.(P36)

生成Pair的便捷函数make_pair()

namespace std {
    // create value pair only by providing the values
    template <class T1, class T2>
    pair<T1, T2> make_pair(const T1 &x, const T2 &y) {
        return pair<T1, T2>(x, y);
    }
}

这样,可以通过:

std::make_pair(100, "TankyWoo");

来代替:

std::pair<int, string>(100, "TankyWoo");

不过,一个算式如果明确指出类型,则带有一个优势:产生出来的pair将有绝对明确的型别,比如:

std::pair<int, float>(100, 8.88);

std::make_pair(100, 8.88)

就不是一个类型,因为第二个元素中,前者是float类型,而后者是double类型(浮点型默认)。

 

  • 3.(P38)

Class auto_ptr

auto_ptr是这样一种指针:它是"它所指的对象"的拥有者(owner)。所以,当身为拥有着的auto_ptr被摧毁时,该对象也遭到摧毁。auto_ptr要求一个对象只能有一个拥有者,严禁一物二主。

比如:

void f()
{
    ClassA* ptr = new ClassA;
    ...
    delete ptr;
}

如果在…的代码中出现异常或return语句等,则ptr无法释放,而造成内存遗失。

void f()
{
    std::auto_ptr<ClassA> ptr(new ClassA);
    ...
}

 

这样就可以解决问题了。

注意,auto_ptr<>不允许使用一般指针惯用的赋值(assign)初始化方式,必须使用直接初始化

eg.

std::auto_ptr<ClassA> ptr1(new ClassA);   // Ok

std::auto_ptr<ClassA> ptr = new ClasssA; // Error

 

  • 4.(P40)

auto_ptr拥有权的转移

通过auto_ptr的copy构造函数和assignment操作符将对象拥有权交出去。

eg.

// transfer ownership from ptr1 to ptr2
std::auto_ptr<ClassA> ptr2(ptr1)

std::auto_ptr<ClassA> ptr2;
ptr2 = ptr1;

如果ptr2被赋值前拥有一个对象,则赋值操作时会调用delete将该对象删除。

因为auto_ptr赋值时会交出拥有权,所以不要在函数的参数列表中使用auto_ptr,也不要以它做返回值。

可以通过引用(reference)传递auto_ptr.

常数型auto_ptr可以减小"不经意转移拥有权"。它意味着不能更改auto_ptr的拥有权,但可以更改auto_ptr所拥有的对象。

eg.

const std::auto_ptr<int> p(new int);

std::auto_ptr<int> q(new int);

*p = 42;  // OK

*p = *q;  // OK

p = q;     // Error

最后来一个实例:

#include <iostream> 
using namespace std; 

template 
<class T> 
ostream
& operator<< (ostream& strm, const auto_ptr<T>& p) 

    
if (p.get() == NULL) { 
         strm 
<< "NULL"
    } 
    
else { 
        strm 
<< *p; 
    } 
    
return strm; 


int main() 
{

    auto_ptr
<int> p(new int(42)); 
    auto_ptr
<int> q; 
    cout 
<< "after initialization:" << endl; 
    cout 
<< " p: " << p << endl; 
    cout 
<< " q: " << q << endl; 
    q 
= p; 
    cout 
<< "after assigning auto pointers:" << endl; 
    cout 
<< " p: " << p << endl; 
    cout 
<< " q: " << q << endl; 
    
*+= 13
    p 
= q; 
    cout 
<< "after changed and assignment:" << endl; 
    cout 
<< " p: " << p << endl; 
    cout 
<< " q: " << q << endl; 

    system(
"PAUSE"); 
    
return EXIT_SUCCESS; 
}

 

输出:

after initialization:
p: 42
q: NULL
after assigning auto pointers:
p: NULL
q: 42
after changed and assignment:
p: 55
q: NULL

 

  • 5.(P66)

三个辅助函数: min(), max(), swap()

都定义在头文件<algorithm>

 

  • 6.(P71)

头文件<cstddef>和<cstdlib>定义了一些常用的常数、宏、型别和函数。

<cstddef>中的定义项

NULL  指针值,表示"未定义"或"无值"

size_t  一种无正负号的型别,用来表示大小(例如元素个数)

ptrdiff_t  一种带有正负号的型别,用来表示指针之间的距离

offsetof  表示一个成员在struct或union的偏移量

<cstdlib>中定义项

exit(int status)  退出(离开,exit)程序

EXIT_SUCCESS 程序正常结束

EXIT_FAILURE  程序不正常结束

abort()  退出程序(在某些系统上可能导致崩溃)

atexit(void(*function)()) 退出(exit)程序时调用某些函数

下面对offsetof介绍下:

offsetof  :
    Retrieves the offset of a member from the beginning of its parent structure.

size_t offsetof(structName, memberName);

Parameters:
    structName : Name of the parent data structure.
    memberName :Name of the member in the parent data structure for which to determine the offset.

Return Value : offsetof returns the offset in bytes of the specified member from
          the beginning of its parent data structure. It is undefined for bit fields.
Remarks :
    The offsetof macro returns the offset in bytes of memberName from the beginning of the structure specified by structName. You can specify types with the struct keyword.

Note  :
    offsetof is not a function and cannot be described using a C prototype.

 

我举了一个例子:

 

// Author: Tanky Woo
// Blog:    www.WuTianQi.com

#include 
<cstddef> 
#include 
<iostream> 
using namespace std; 

typedef 
struct TK { 
    
char a; 
    
int b; 
    
char c; 
}TK; 

int main() 

    cout 
<< offsetof(TK, a) << endl; 
    cout 
<< offsetof(TK, b) << endl; 
    cout 
<< offsetof(TK, c) << endl; 
    system(
"PAUSE"); 
    
return EXIT_SUCCESS; 
}

 

里面涉及到了内存对齐问题,关于内存对齐的详细文章,我在其他地方发过:

因为博客园把网址禁止了。大家可以去本文的原文看,那里给出了内存对齐的网址。

原文:http://www.wutianqi.com/?p=2036

posted on 2011-01-24 13:57  Tanky Woo  阅读(1865)  评论(0编辑  收藏  举报

导航