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. UVA 11186 Circum Triangle (枚举三角形优化)(转)

    题意:圆上有n个点,求出这n个点组成的所有三角形的面积之和 题解: 当我们要求出S(i,j,k)时,我们需要假设k在j的左侧,k在i与j之间,k在i的右侧. 如果k在 j的左侧  那么 S(i,j,k ...

  2. Spring初学之注解方式配置bean

    直接看代码: UserController.java package spring.beans.annotation.controller; import org.springframework.be ...

  3. 应用程序.f/q(f了个墙)

    1.20180414: 前两天,发现 CnFast不能用了,也没管它 以为过两天会好. 今天发现还是不能用,上网随便baidu下,看到个帖子:有人用加速精灵吗 现在登陆不了了 哪位大佬知道怎么回事啊[ ...

  4. Java JDK、Tomcat、Eclipse环境配置

    Java 下载地址:http://www.oracle.com/ 根据提示一步一步进行安装,通常安装到C:\Program Files\Java,包含: 环境变量配置: JAVA_HOME:C:\Pr ...

  5. java/jsp: 登录系统

    db类   package db; import java.sql.*; import javax.naming.InitialContext; import javax.sql.DataSource ...

  6. poj3189二分图多重匹配

    题意:有一些牛和牛棚(有容量),每头牛对牛棚有喜好程度,要求每头牛都有一个棚子的情况下,找最小的喜好程度之差 题解:题意是真的恶心,wa了好久才发现没读懂,一直以为输入 的是排名,其实是牛棚标号,从1 ...

  7. mysql插入一万条数据

    定义一个存储过程 mysql> delimiter $$ mysql> create procedure ptest()    -> begin    -> declare p ...

  8. centos下安装storm

    centOS安装ZeroMQ centOS安装ZeroMQ所需组件及工具: yum install gcc yum install gcc-c++ yum install make yum insta ...

  9. spring MVC multipart处理文件上传

    在开发Web应用程序时比较常见的功能之一,就是允许用户利用multipart请求将本地文件上传到服务器,而这正是Grails的坚固基石——Spring MVC其中的一个优势.Spring通过对Serv ...

  10. IE9 placeholder 不兼容的解决

    坑爹的IE9-,真的是够够的了,不过公司不要求兼容这个玩意了,自己觉得兼容这个鬼还是挺有挑战性的,自己也碰到不少难题,一个个解决. css: .placeholderColor { color : # ...