layout: post

title: 侯捷STL学习(12)

date: 2017-08-01

tag: 侯捷STL

第四讲 STL相关的内容

Hash Function

  • 将hash函数封装成类对象

  • hash_val进行拆解传入参数,进行循环
  • 每次拆解一个参数,都需要更新种子
  • TR1的工具,)0x9e3779b9是黄金比例数字0.618

  • 测试

  • 当没有指定hash函数时,用默认的hash函数,但是针对特殊的类型,有自己特化的hash函数

tuple用例

  • 测试

  • 实现,递归的继承实现自动添加任意多个函数,需要有终止条件无参数偏特化版本
  • 元组大小决定由类的继承关系决定

type traits

  • 测试,traits回答type的类型

  • 区别拷贝和‘搬运’构造函数

cout

  • cout继承关系,把已有的类型放入cout才可以输出

moveable

  • 深浅拷贝
  • 使用move后,保证原来的地址不在使用



  • 测试
using namespace std;
const long ASIZE = 500000L; //----------------------------------------------------
#include <iostream>
#include <cstdio> //snprintf()
#include <cstdlib> //RAND_MAX
#include <cstring> //strlen(), memcpy()
#include <string>
using std::cin;
using std::cout;
using std::string; //以下 MyString 是為了測試 containers with moveable elements 效果.
class MyString {
public:
static size_t DCtor; //累計 default-ctor 的呼叫次數
static size_t Ctor; //累計 ctor 的呼叫次數
static size_t CCtor; //累計 copy-ctor 的呼叫次數
static size_t CAsgn; //累計 copy-asgn 的呼叫次數
static size_t MCtor; //累計 move-ctor 的呼叫次數
static size_t MAsgn; //累計 move-asgn 的呼叫次數
static size_t Dtor; //累計 dtor 的呼叫次數
private:
char* _data;
size_t _len;
void _init_data(const char *s) {
_data = new char[_len+1];
memcpy(_data, s, _len);
_data[_len] = '\0';
}
public:
//default ctor
MyString() : _data(NULL), _len(0) { ++DCtor; } //ctor
MyString(const char* p) : _len(strlen(p)) {
++Ctor;
_init_data(p);
} // copy ctor
MyString(const MyString& str) : _len(str._len) {
++CCtor;
_init_data(str._data); //COPY
} //move ctor, with "noexcept"
MyString(MyString&& str) noexcept : _data(str._data), _len(str._len) {
++MCtor;
str._len = 0;
str._data = NULL; //避免 delete (in dtor)
} //copy assignment
MyString& operator=(const MyString& str) {
++CAsgn;
if (this != &str) {
if (_data) delete _data;
_len = str._len;
_init_data(str._data); //COPY!
}
else {
// Self Assignment, Nothing to do.
}
return *this;
} //move assignment
MyString& operator=(MyString&& str) noexcept {
++MAsgn;
if (this != &str) {
if (_data) delete _data;
_len = str._len;
_data = str._data; //MOVE!
str._len = 0;
str._data = NULL; //避免 deleted in dtor
}
return *this;
} //dtor
virtual ~MyString() {
++Dtor;
if (_data) {
delete _data;
}
} bool
operator<(const MyString& rhs) const //為了讓 set較大小
{
return std::string(this->_data) < std::string(rhs._data); //借用事實:string 已能比較大小.
}
bool
operator==(const MyString& rhs) const //為了讓 set 判斷相等.
{
return std::string(this->_data) == std::string(rhs._data); //借用事實:string 已能判斷相等.
} char* get() const { return _data; }
};
size_t MyString::DCtor=0;
size_t MyString::Ctor=0;
size_t MyString::CCtor=0;
size_t MyString::CAsgn=0;
size_t MyString::MCtor=0;
size_t MyString::MAsgn=0;
size_t MyString::Dtor=0; namespace std //必須放在 std 內
{
template<>
struct hash<MyString> //這是為了 unordered containers
{
size_t
operator()(const MyString& s) const noexcept
{ return hash<string>()(string(s.get())); }
//借用現有的 hash<string> (in ...\include\c++\bits\basic_string.h)
};
}
//-----------------
//以下 MyStrNoMove 是為了測試 containers with no-moveable elements 效果.
class MyStrNoMove {
public:
static size_t DCtor; //累計 default-ctor 的呼叫次數
static size_t Ctor; //累計 ctor 的呼叫次數
static size_t CCtor; //累計 copy-ctor 的呼叫次數
static size_t CAsgn; //累計 copy-asgn 的呼叫次數
static size_t MCtor; //累計 move-ctor 的呼叫次數
static size_t MAsgn; //累計 move-asgn 的呼叫次數
static size_t Dtor; //累計 dtor 的呼叫次數
private:
char* _data;
size_t _len;
void _init_data(const char *s) {
_data = new char[_len+1];
memcpy(_data, s, _len);
_data[_len] = '\0';
}
public:
//default ctor
MyStrNoMove() : _data(NULL), _len(0) { ++DCtor; _init_data("jjhou"); } //ctor
MyStrNoMove(const char* p) : _len(strlen(p)) {
++Ctor; _init_data(p);
} // copy ctor
MyStrNoMove(const MyStrNoMove& str) : _len(str._len) {
++CCtor;
_init_data(str._data); //COPY
} //copy assignment
MyStrNoMove& operator=(const MyStrNoMove& str) {
++CAsgn; if (this != &str) {
if (_data) delete _data;
_len = str._len;
_init_data(str._data); //COPY!
}
else {
// Self Assignment, Nothing to do.
}
return *this;
} //dtor
virtual ~MyStrNoMove() {
++Dtor;
if (_data) {
delete _data;
}
} bool
operator<(const MyStrNoMove& rhs) const //為了讓 set 比較大小
{
return string(this->_data) < string(rhs._data); //借用事實:string 已能比較大小.
} bool
operator==(const MyStrNoMove& rhs) const //為了讓 set 判斷相等.
{
return string(this->_data) == string(rhs._data); //借用事實:string 已能判斷相等.
} char* get() const { return _data; }
};
size_t MyStrNoMove::DCtor=0;
size_t MyStrNoMove::Ctor=0;
size_t MyStrNoMove::CCtor=0;
size_t MyStrNoMove::CAsgn=0;
size_t MyStrNoMove::MCtor=0;
size_t MyStrNoMove::MAsgn=0;
size_t MyStrNoMove::Dtor=0; namespace std //必須放在 std 內
{
template<>
struct hash<MyStrNoMove> //這是為了 unordered containers
{
size_t
operator()(const MyStrNoMove& s) const noexcept
{ return hash<string>()(string(s.get())); }
//借用現有的 hash<string> (in ...\4.9.2\include\c++\bits\basic_string.h)
};
} //----------------------------------------------------
#include <iostream>
#include <cstdio> //snprintf()
#include <cstdlib> //RAND_MAX
#include <string>
#include <algorithm>
#include <list>
#include <forward_list>
using std::cin;
using std::cout;
using std::string;
using std::max;
using std::min; namespace jj00
{ bool strLonger(const string& s1, const string& s2) {
return s1.size() < s2.size();
} void test_misc()
{
cout << "\ntest_misc().......... \n"; //以下這些是標準庫的眾多容器的 max_size() 計算方式.
cout << size_t(-1) << endl; //4294967295
cout << size_t(-1)/sizeof(long) << endl; //1073741823
cout << size_t(-1)/sizeof(string) << endl; //1073741823
cout << size_t(-1)/sizeof(_List_node<string>) << endl; //357913941
cout << size_t(-1)/sizeof(_Fwd_list_node<string>) << endl; //536870911
cout << "RAND_MAX= " << RAND_MAX << endl; //32767 cout << min( {2,5,8,9,45,0,81} ) << endl; //0
cout << max( {2,5,8,9,45,0,81} ) << endl; //81
vector<int> v {2,5,8,9,45,0,81}; cout << "max of zoo and hello : "
<< max(string("zoo"), string("hello")) << endl; //zoo
cout << "longest of zoo and hello : "
<< max(string("zoo"), string("hello"), strLonger) << endl; //hello cout << hash<MyString>()(MyString("Ace")) << endl; //1765813650
cout << hash<MyString>()(MyString("Stacy")) << endl; //2790324277
cout << "MyString(zoo) < MyString(hello) ==> " << (MyString("zoo") < MyString("hello")) << endl; //0
cout << "MyString(zoo) == MyString(hello) ==> " << (MyString("zoo") == MyString("hello")) << endl; //0
cout << "MyStrNoMove(zoo) < MyStrNoMove(hello) ==> " << (MyStrNoMove("zoo") < MyStrNoMove("hello")) << endl; //0
cout << "MyStrNoMove(zoo) == MyStrNoMove(hello) ==> " << (MyStrNoMove("zoo") == MyStrNoMove("hello")) << endl; //0
//以上建構了 6 個 MyString objects 和 4 個 MyStrNoMove objects,都是暫時生命.
}
}
//--------------------------------------------------
#include <typeinfo> //typeid()
template<typename T>
void output_static_data(const T& myStr)
{
cout << typeid(myStr).name() << " -- " << endl;
cout << " CCtor=" << T::CCtor
<< " MCtor=" << T::MCtor
<< " CAsgn=" << T::CAsgn
<< " MAsgn=" << T::MAsgn
<< " Dtor=" << T::Dtor
<< " Ctor=" << T::Ctor
<< " DCtor=" << T::DCtor
<< endl;
} #include <ctime> //clock_t, clock()
template<typename M, typename NM>
void test_moveable(M c1, NM c2, long& value)
{
char buf[10]; //測試 move
cout << "\n\ntest, with moveable elements" << endl;
typedef typename iterator_traits<typename M::iterator>::value_type V1type;
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
snprintf(buf, 10, "%d", rand());
auto ite = c1.end();
c1.insert(ite, V1type(buf));
}
cout << "construction, milli-seconds : " << (clock()-timeStart) << endl;
cout << "size()= " << c1.size() << endl;
output_static_data(*(c1.begin())); timeStart = clock();
M c11(c1);
cout << "copy, milli-seconds : " << (clock()-timeStart) << endl; timeStart = clock();
M c12(std::move(c1));
cout << "move copy, milli-seconds : " << (clock()-timeStart) << endl; timeStart = clock();
c11.swap(c12);
cout << "swap, milli-seconds : " << (clock()-timeStart) << endl; //測試 non-moveable
cout << "\n\ntest, with non-moveable elements" << endl;
typedef typename iterator_traits<typename NM::iterator>::value_type V2type;
timeStart = clock();
for(long i=0; i< value; ++i)
{
snprintf(buf, 10, "%d", rand());
auto ite = c2.end();
c2.insert(ite, V2type(buf));
} cout << "construction, milli-seconds : " << (clock()-timeStart) << endl;
cout << "size()= " << c2.size() << endl;
output_static_data(*(c2.begin())); timeStart = clock();
NM c21(c2);
cout << "copy, milli-seconds : " << (clock()-timeStart) << endl; timeStart = clock();
NM c22(std::move(c2));
cout << "move copy, milli-seconds : " << (clock()-timeStart) << endl; timeStart = clock();
c21.swap(c22);
cout << "swap, milli-seconds : " << (clock()-timeStart) << endl;
}

侯捷STL学习(12)--STL相关内容hash+tuple的更多相关文章

  1. From COM to COM 侯捷 1998.06.12

    摘要: 本文簡介 C++ Object Model 和 Component Object Model 的基本概念,並引介四本書籍: 1. Inside The C++ Object Model 2. ...

  2. STL学习:STL库vector、string、set、map用法

    本文仅介绍了如何使用它们常用的方法. vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1 ...

  3. Binary Search 的递归与迭代实现及STL中的搜索相关内容

    与排序算法不同,搜索算法是比较统一的,常用的搜索除hash外仅有两种,包括不需要排序的线性搜索和需要排序的binary search. 首先介绍一下binary search,其原理很直接,不断地选取 ...

  4. 【STL学习】堆相关算法详解与C++编程实现(Heap)

    转自:https://blog.csdn.net/xiajun07061225/article/details/8553808 堆简介   堆并不是STL的组件,但是经常充当着底层实现结构.比如优先级 ...

  5. STL学习笔记---STL简介

    1.概述 STL是通用类模版和算法的集合,它提供给程序员一些标准的数据结构和算法的实现.STL三大关键组成: 容器(Containers),用来管理类对象的集合 迭代器(Iterators),用来在一 ...

  6. 侯捷C++学习(一)

    //c++学习//标准库非常重要//要规范自己的代码complex c1(2,1);complex c2;complex* pc = new complex(0,1);string s1(" ...

  7. 侯捷C++学习(二)

    #include <iostream>using namespace std;class complex{ public: complex (double r= 0, double i = ...

  8. ###STL学习--vector

    点击查看Evernote原文. #@author: gr #@date: 2014-08-11 #@email: forgerui@gmail.com vector的相关问题.<stl学习> ...

  9. 评侯捷的<深入浅出MFC>和李久进的<MFC深入浅出>

    侯捷的<深入浅出mfc>相信大家都已经很熟悉了,论坛上也有很多介绍,这里我就不多说了. 而李久进的<mfc深入浅出>,听说的人可能就少得多.原因听说是这本书当时没有怎么宣传,而 ...

随机推荐

  1. 最短路径Dijkstra模板

    算法思想:把所有的边分成两个集合A,B.集合A表示已经求出最短路径的点,不断扩展集合A,减少集合B.每一扩展就从结合B中找出到源点距离最短的点,加入到A. dis[i]数组代表从出发点到j的距离: m ...

  2. Luogu-4022 [CTSC2012]熟悉的文章

    广义后缀自动机+DP 对于作文库建出广义后缀自动机,广义自动机就是在每次添加一个字符串之前把\(last=0\),然后正常添加就好了 对于每个询问串,预处理出每个位置\(i\)能向前匹配的最长长度\( ...

  3. codeforces707C:Pythagorean Triples

    Description Katya studies in a fifth grade. Recently her class studied right triangles and the Pytha ...

  4. POJ2741 Colored Cubes

    Description There are several colored cubes. All of them are of the same size but they may be colore ...

  5. Codeforces Round #367 (Div. 2) A , B , C

    A. Beru-taxi time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  6. SaaS架构经验总结

    2B Saas系统最近几年都很火.很多创业公司都在尝试创建企业级别的应用 cRM, HR,销售, Desk Saas系统.很多Saas创业公司也拿了大额风投.毕竟Saas相对传统软件的优势非常明显. ...

  7. python global

    如果想在函数内部改变函数外的变量值,用global语句完成: 在不传该变量值入函数的情况下要改变它的值: >>> a = 3 >>> def f(): ... gl ...

  8. Memcache笔记(1)

    缓存主要分为:页面缓存和数据缓存 Memcache .redis.mongodb都是做数据缓存的 Memcache是什么? 是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的ha ...

  9. HTTP通道

    通过httptunnel技术进行入侵示例 httptunnel是通过HTTP通道来传输其他协议数据的工具软件,下载地址为:www.http-tunnel. com,目前最新版本3.0.5 工具/原料 ...

  10. crontab 总结

    crontab -e --------- linux定时任务提示-bash: crontab: command not found 执行 crontab 命令如果报 command not found ...