- 1.(P33)
Pairs(对组)的定义 class pair可以将两个值视为一个单元。map和multimap就是通过pair来管理键值/实值(key/value)的。 在pair的定义中:
namespace std {
template
struct pair {
// member
T1 first;
T2 second;
...
// copy construct with implicit conversions
template
pair(cosnt pair & 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
pair make_pair(const T1 &x;, const T2 &y;) {
return pair(x, y);
}
}
这样,可以通过:
std::make_pair(100, "TankyWoo");
来代替:
std::pair(100, "TankyWoo");
不过,一个算式如果明确指出类型,则带有一个优势:产生出来的pair将有绝对明确的型别,比如:
std::pair(100, 8.88);
和
std::make_pair(100, 8.88)
就不是一个类型,因为第二个元素中,前者是float类型,而后者是double类型(浮点型默认)。
- 3.(P38)
Class autoptr autoptr是这样一种指针:它是"它所指的对象"的拥有者(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 ptr1(new ClassA); // Ok
std::auto_ptr ptr = new ClasssA; // Error
- 4.(P40)
autoptr拥有权的转移 通过autoptr的copy构造函数和assignment操作符将对象拥有权交出去。 eg.
// transfer ownership from ptr1 to ptr2
std::auto_ptr ptr2(ptr1)
或
std::auto_ptr ptr2;
ptr2 = ptr1;
如果ptr2被赋值前拥有一个对象,则赋值操作时会调用delete将该对象删除。 因为autoptr赋值时会交出拥有权,所以不要在函数的参数列表中使用autoptr,也不要以它做返回值。 可以通过引用(reference)传递autoptr. 常数型autoptr可以减小"不经意转移拥有权"。它意味着不能更改autoptr的拥有权,但可以更改autoptr所拥有的对象。 eg.
const std::auto_ptr p(new int);
std::auto_ptr q(new int);
*p = 42; // OK
*p = *q; // OK
p = q; // Error
最后来一个实例:
#include
using namespace std;
template
ostream& operator<< (ostream& strm, const auto_ptr& p)
{
if (p.get() == NULL) {
strm << "NULL";
}
else {
strm << *p;
}
return strm;
}
int main()
{
auto_ptr p(new int(42));
auto_ptr 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;
*q += 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() 都定义在头文件
- 6.(P71)
头文件和定义了一些常用的常数、宏、型别和函数。 中的定义项 NULL 指针值,表示"未定义"或"无值" sizet 一种无正负号的型别,用来表示大小(例如元素个数) ptrdifft 一种带有正负号的型别,用来表示指针之间的距离 offsetof 表示一个成员在struct或union的偏移量
中定义项 exit(int status) 退出(离开,exit)程序 EXITSUCCESS 程序正常结束 EXITFAILURE 程序不正常结束 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
#include
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.cppleyuan.com/viewthread.php?tid=17&highlight=%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90
http://www.cppleyuan.com/viewthread.php?tid=18&highlight=%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90