侯捷C++(STL和泛型编程)

Remember Understand Practice Use Understand Master

一、STL和泛型编程

C++标准库

C++标准模板库

STL六大部件:

容器(Containers)

分配器(Allocators)

算法(Algorithms)

迭代器(Iterators)

适配器(Adapters)

仿函式(Functors)

#include <iostream>

using namespace std;

int main()
{
    for(int i: {2,3,5,7,9,13,17,19})
        {
            cout<<i<<' ';
        }
    return 0;
}

1.容器

Sequence containers:

Array

Vector

  heap

    priority——queue

优先队列是一种容器适配器,采用了堆这样的数据结构,保证了第一个元素总是整个优先队列中最大的(或最小的)元素。优先队列默认使用vector作为底层存储数据的容器

Deque

Stack

Queue

List

Slist

Forward-List

Associative containers:

Set/Multiset

Map/Multimap

Unordered Set/Multiset

Unordered Map/Multimap

2.分配器

面向对象编程VS泛型编程

Operator Overloading操作符重载

Templates 模板

ClassTemplates 类模板

Function Templates 函数模板

Member Templates 成员模板

 

检查数据类型

typeid() typeid 用于在编译时获取类型的 Type

3.算法

4.迭代器的分类

二、C++标准11-14

   C++ Primer回顾:

  1.可以用sizeof测量数据类型的大小,以字节为单位

1.类定义

类成员

一般情况下,数据成员为private

没写访问标号,默认private

构造函数

使用初始化列表初始化数据成员

Person(const string &nm,const string &addr):name(nm),address(addr){
        //name = nm;
        //address = addr;
    }

成员函数

访问标号实施抽象和封装

 public

 private

 protected

 

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

class Sales_item
{
public:
    Sales_item(string &book,unsigned units,double amount):
        isbn(book),units_sold(units),revenue(amount)
        {

        }
    double avg_price() const
    {
        if(units_sold)
            return revenue / units_sold;
        else
            return 0;
    }
    bool same_isbn(const Sales_item &rhs) const
    {
        return isbn == rhs.isbn;
    }

    void add(const Sales_item &rhs)
    {
        units_sold += rhs.units_sold;
        revenue += rhs.revenue;
    }
private:
    string isbn;
    unsigned units_sold;
    double revenue;
};

class Person{
public:
    Person(const string &nm,const string &addr):name(nm),address(addr){
        //name = nm;
        //address = addr;
    }
    string getName() const
    {
        return name;
    }
    string getAddress() const
    {
        return address;
    }
private:
    string name;
    string address;
};

int main()
{
    //Person a("bill","street1");
    //a.name;
    //cout<<a.getName();
    //a.getAddress();
    string s("0-399-82477-1");
    Sales_item x(s,2,20.00);
    Sales_item y(s,6,48.00);

    if(x.same_isbn(y))
        x.add(y);
    cout<<x.avg_price()<<endl;
    cout<<y.avg_price();

    return 0;
}

2.  

       同一类型的多个数据成员

  使用类型别名来简化类

  成员函数可被重载 - 定义重载成员函数

  显法指定inline成员函数

写在类内部的函数都是内联函数。

函数定义写在外部则不是内联函数,可在定义或声明前增加inline

#include <iostream>
#include <string>

using namespace std;

class Screen
{
public:
    typedef string::size_type index;

    Screen(index ht = 0,index wd = 0):contents(ht*wd,'A'),cursor(0),height(ht),width(wd)
    {

    }

    Screen(index ht,index wd,const string &conts);

    char get() const;
    inline char get(string::size_type r,string::size_type c) const;

private:
    string contents;
    string::size_type cursor;
    string::size_type height,width;
};

inline char Screen::get() const
{
    return contents[cursor];
}

char Screen::get(string::size_type r,string::size_type c) const
{
    string::size_type row = r*width;
    return contents[row+c];
}

Screen::Screen(index ht,index wd,const string &conts):contents(conts),
cursor(0),height(ht),width(wd)
{

}

int main()
{
    Screen a(10,100);
    cout<<a.get()<<endl;
    cout<<a.get(2,8)<<endl;

    Screen b(3,6,"hello screen class");
    cout<<b.get()<<endl;
    cout<<b.get(0,4)<<endl;
    cout<<b.get(1,2);
    return 0;
}

3.隐含的this指针

this指向当前的对象

何时使用this指针

返回*this

从const成员函数返回*this

基于const的重载

可变数据成员

4.类作用域

1.使用类的成员

2.作用域与成员定义

3.形参表和函数体处于类作用域中

4.函数返回类型不一定在类作用域中

类作用域中的名字查找

1.类成员声明的名字查找

2.类成员定义中的名字查找

3.类成员遵循常规的块作用域名字查找

4.函数作用域之后,在类作用域中查找

5.类作用域之后,在外围作用域中查找 

 5.构造函数

作用保证每个对象的数据成员具有合适的初始值

构造函数初始化式(初始化列表)

默认实参与构造函数

默认构造函数

对string进行初始化为空,其他类型没有默认初始化

const成员、引用类型、没有默认构造函数的类类型必须使用初始化列表

隐式类类型转换

类成员的显示初始化

#include<iostream>
#include <string>

using namespace std;

class Person
{
public:
    Person(const string &nm,int a):name(nm),age(a)
    {

    }
public:
    string name;
    int age;
};

class Dog
{
public:
    Dog()
    {
        this->legs = 4;
    }
private:
    string name;
    int legs;
};

class Sales_item
{
public:
    Sales_item(const string &book,int units,double price):isbn(book),units_sold(units),revenue(units*price)
    {

    }
    //默认的实参,不给参数按照默认的
    Sales_item(const string &book=""):isbn(book),units_sold(0),revenue(0.0){}
    Sales_item(istream &is) {is >> *this;}
    //Sales_item():units_sold(0),revenue(0.0){}
    Sales_item(int units,double price)
    {
        this->units_sold = units;
        this->revenue = units*price;
    }
    friend istream& operator >> (istream&,Sales_item&);
private:
    string isbn;
    unsigned units_sold;
    double revenue;
};

inline istream& operator>>(istream& in,Sales_item& s)
{
    double price;
    in>>s.isbn>>s.units_sold>>price;
    if(in)
        s.revenue = s.units_sold * price;
    else
        s = Sales_item();
    return in;
}

class Cat{
public:
    Cat():age(0){}
    string getName(){
        return this->name;
    }
    int getAge()
    {
        return this->age;
    }
private:
    string name;
    int age;
};

int main()
{
    Person a("zhangfei",22);
    cout<<a.name<<endl;
    cout<<a.age;
    Sales_item item1;
    Sales_item item2("0-201-82470-1");
    Sales_item *p = new Sales_item();

    delete [] p;
    return 0;
}

6.友元-友元函数、友元类

友元关系

三种友元

1.普通函数(非成员函数)

2.类

3.类的成员函数

#include <iostream>
#include <string>

using namespace std;

class Screen;

class Dog
{
public:
    int foo(Screen& screen);
    int koo(Screen& screen);
};

class Screen
{
public:
    typedef string::size_type index;
    Screen(int ht=0,int wd=0):contents(ht*wd,' '),cursor(0),height(ht),width(wd)
    {

    }
    int area() const
    {
        return height*width;
    }

    friend int calcArea(Screen &);
    friend class Window_Mgr;
    //friend class Dog;
    friend int Dog::foo(Screen&);
private:
    string contents;
    index cursor;
    int height,width;
};

class Window_Mgr
{
public:
    void relocate(int r,int c,Screen& s)
    {
        s.height += r;
        s.width += c;
    }
};

// 这个函数不是类的成员函数
int calcArea(Screen &screen)
{
    return screen.height * screen.width;
}

int Dog::foo(Screen& screen)
{
    return screen.height * screen.width;
}

int main()
{
    Screen a(60,100);
    cout<<a.area()<<endl;
    Window_Mgr wm;
    wm.relocate(20,100,a);
    cout<<calcArea(a)<<endl;
    Dog dog;
    cout<<dog.foo(a)<<endl;
//    cout<<dog.koo(a)<<endl;
    cout<<"OK"<<endl;
    return 0;
}

7.static类成员

使用类的static成员的优点

公用

定义static成员

使用类的static成员

static成员函数

static数据成员

#include <iostream>
#include <string>

using namespace std;

class Account
{
public:
    Account(string name,double money):
        owner(name),amount(money)
        {

        }
    double getAmount() const
    {
        return this->amount;
    }

    void applyint()
    {
        amount+=amount*interestRate;
    }

    void deposit(double money)
    {
        this->amount += money;
    }

    static double rate()
    {
        return interestRate;
    }

    static void rate(double newRate){interestRate = newRate;}
private:
    string owner;
    double amount;
    static double interestRate;
    static const int period = 30;//例外
};

double Account::interestRate = 0.015;

int main()
{
    Account::rate(0.026);
    Account a("zhangsan",1000);
    a.deposit(500);
    Account b("lisi",2000);
    b.deposit(600);

    cout<<a.getAmount()<<endl;
    cout<<b.getAmount()<<endl;

    cout<<a.rate()<<endl;
    a.rate(0.018);
    cout<<b.rate()<<endl;

    Account::rate(0.02);
    a.applyint();
    b.applyint();
    cout<<a.getAmount()<<endl;
    cout<<b.getAmount()<<endl;
    return 0;
}

8.复制构造函数和赋值操作符

复制构造函数的适用情况

1.对象的定义形式 - 复制初始化

2.形参与返回值

3.初始化容器元素

4.构造函数与数组元素

赋值操作符

1.重载赋值操作符

2.复制和赋值常一起使用

合成的复制构造函数和赋值操作符

定义自己的复制构造函数和赋值操作符

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Sales_item
{
public:
    //普通构造函数
    Sales_item():units_sold(0),revenue(0.0){
        cout<<"This 1"<<endl;
    }
    Sales_item(const string &book):isbn(book),units_sold(0),revenue(0.0)
    {
        cout<<"This 2"<<endl;
    }
    //复制构造函数
    Sales_item(const Sales_item &orig):isbn(orig.isbn),
    units_sold(orig.units_sold),revenue(orig.revenue)
    {
        cout<<"DYL"<<endl;
    }
    //赋值操作符 当类中动态分配内存时,必须重载赋值操作符
    Sales_item& operator=(const Sales_item &rhs)
    {
        cout<<"DYLLLLLL"<<endl;
        isbn = rhs.isbn;
        units_sold = rhs.units_sold;
        revenue = rhs.revenue;
        return *this;
    }
private:
    string isbn;
    unsigned units_sold;
    double revenue;
};

Sales_item foo(Sales_item &item)
{
    Sales_item temp;
    temp = item;
    return temp;
}

class noName
{
public:
    noName():pstring(new string),
    i(0),d(0.0)
    {

    }
    noName(const noName& other):pstring(new string(*(other.pstring))),
    i(other.i),d(other.d)
    {

    }

    noName& operator=(const noName &rhs)
    {
        pstring = new string;
        *pstring = *(rhs.pstring);
        i=rhs.i;
        d=rhs.d;
        return *this;
    }
private:
    string *pstring;
    int i;
    double d;
};

int main()
{
    noName x,y;
    noName z(x);
    x = y;

    Sales_item a;
    Sales_item b("0-201-78345-X");
    Sales_item c(b);
    a = b;
    Sales_item item = string("9-999-99999-9");

    cout<<"try foo()"<<endl;
    Sales_item ret;
    ret = foo(item);

    cout<<"try vector"<<endl;
    vector<Sales_item> vec(5);

    cout<<"try array"<<endl;
    Sales_item primer_eds[] = {
        string("0-201-16487-6"),
        string("0-201-16487-7"),
        string("0-201-16487-7"),
        Sales_item()
    };
    return 0;
}

9.析构函数

析造函数:获取资源

析构函数:释放资源

合成的析构函数

三法则:如果写了析构函数,一定要写复制构造函数和赋值操作符重载。

#include <iostream>

using namespace std;

class NoName
{
public:
    NoName():pstring(new string),i(0),d(0.0)
    {
        cout<<"构造函数被调用了"<<endl;
    }
    ~NoName();
    NoName(const NoName& other);
    NoName& operator=(const NoName &rhs);
private:
    string *pstring;
    int i;
    double d;
};

NoName::~NoName()
{
    //关闭文件
    //关闭数据库链接
    //回收动态分配的内存
    cout<<"析构函数被调用了"<<endl;
    delete pstring;
}
NoName::NoName(const NoName& other)
{
    pstring = new string();
    *pstring = *(other.pstring);
    i = other.i;
    d = other.d;
}

NoName& NoName::operator=(const NoName &rhs)
{
    pstring = new string;
    *pstring = *(rhs.pstring);
    i = rhs.i;
    d = rhs.d;
    return *this;
}

int main()
{
    NoName a;
    NoName *p = new NoName;
    delete p;
    return 0;
}

10.深复制、浅复制

复制构造函数/拷贝构造函数

浅复制/浅拷贝/位拷贝

深复制/深拷贝

#include <iostream>
#include <cstring>

using namespace std;

class CDemo
{
    //默认的复制构造函数是浅复制
public:
    CDemo(int pa,char *cstr)
    {
        this->a = pa;
        this->str = new char[104];
        strcpy(this->str,cstr);
    }

    CDemo(CDemo &obj)
    {
        this->a = obj.a;
        this->str = new char[1024];
        if(str!=0)
            strcpy(this->str,obj.str);
    }

    ~CDemo()
    {
        delete str;
    }
    int a;
    char *str;
};

int main()
{
    CDemo A(10,"hello");
    CDemo B = A;
    cout<<A.a<<" "<<A.str<<endl;
    cout<<B.a<<" "<<B.str<<endl;
    B.a = 8;
    B.str[0]='k';
    cout<<A.a<<" "<<A.str<<endl;
    cout<<B.a<<" "<<B.str<<endl;
    return 0;
}

11.管理指针成员

三种方法

1.常规指针类(浅复制)

严重缺点:野指针(悬垂指针)

class AHasPtr
{
public:
    AHasPtr(int *p,int i):ptr(p),val(i)
    {

    }
    int *get_ptr() const {return ptr;}
    int get_int() const {return val;}

    void set_ptr(int *p) {ptr=p;}
    void set_int(int i){val=i;}

    int get_ptr_val() const {return *ptr;}
    void set_ptr_val(int val) {*ptr = val;}
private:
    int val;
    int *ptr;
};

2.智能指针类(计数类)

避免野指针

class CHasPtr
{
public:
    CHasPtr(const int &p,int i):ptr(new int(p)),val(i)
    {

    }
    CHasPtr(const CHasPtr &orig):ptr(new int(*orig.ptr)),
    val(orig.val){}
    CHasPtr& operator=(const CHasPtr&);

    ~CHasPtr()
    {
        delete ptr;
    }
    int *get_ptr() const {return ptr;}
    int get_int() const {return val;}

    void set_ptr(int *p) {ptr=p;}
    void set_int(int i){val=i;}

    int get_ptr_val() const {return *ptr;}
    void set_ptr_val(int val) {*ptr = val;}
private:
    int val;
    int *ptr;
};

CHasPtr& CHasPtr::operator=(const CHasPtr &rhs)
{
    *ptr = *rhs.ptr;
    val = rhs.val;
    return *this;
}

3.值型类(深复制)

class U_Ptr
{
    friend class BHasPtr;
private:
    int *ip;
    size_t use;//计数
    U_Ptr(int *p):ip(p),use(1){}
    ~U_Ptr(){delete ip;}
};

class BHasPtr
{
public:
    BHasPtr(int *p,int i):ptr(new U_Ptr(p)),val(i)
    {

    }
    BHasPtr(const BHasPtr& orig):ptr(orig.ptr),val(orig.val){
        ++ptr->use;
    }
    BHasPtr& operator=(const BHasPtr&);
    ~BHasPtr()
    {
        //此处似乎有问题
        //if(--ptr->use == 0)
        delete ptr;

    }
    int *get_ptr() const {return ptr->ip;}
    int get_int() const {return val;}

    void set_ptr(int *p) {ptr->ip=p;}
    void set_int(int i){val=i;}

    int get_ptr_val() const {return *ptr->ip;}
    void set_ptr_val(int val) {*ptr->ip = val;}
private:
    int val;
    U_Ptr *ptr;
};

BHasPtr& BHasPtr::operator=(const BHasPtr &rhs)
{
    ++rhs.ptr->use;
    if(--ptr->use == 0) delete ptr;

    ptr = rhs.ptr;
    val = rhs.val;
    return *this;
}

  

#include <iostream>
#include "plain-ptr.h"
#include "value-ptr.h"
#include "smart-ptr.h"

using namespace std;

void test_AHasPtr()
{
    int i=42;
    AHasPtr p1(&i,42);
    AHasPtr p2 = p1;
    cout<<p2.get_ptr_val()<<endl;

    p1.set_ptr_val(0);
    cout<<p2.get_ptr_val()<<endl;

    int *ip = new int(42);
    AHasPtr ptr(ip,10);
    cout<<ptr.get_ptr_val()<<endl;
    delete ip;
    cout<<ptr.get_ptr_val()<<endl;
}

void test_CHasPtr()
{
    int obj = 0;
    CHasPtr ptr1(obj,42);
    CHasPtr ptr2(ptr1);

    cout<<ptr1.get_ptr_val()<<endl;
    cout<<ptr1.get_int()<<endl;
    cout<<ptr2.get_ptr_val()<<endl;
    cout<<ptr2.get_int()<<endl;
    ptr2.set_ptr_val(10);
    cout<<ptr1.get_ptr_val()<<endl;
    cout<<ptr1.get_int()<<endl;
    cout<<ptr2.get_ptr_val()<<endl;
    cout<<ptr2.get_int()<<endl;

}

void test_BhasPtr()
{
    int obj=0;
    BHasPtr ptr1(&obj,42);
    BHasPtr ptr2(ptr1);
    cout<<ptr1.get_ptr_val()<<","<<ptr1.get_int()<<endl;
    cout<<ptr2.get_ptr_val()<<","<<ptr2.get_int()<<endl;
    ptr2.set_ptr_val(39);
    ptr1.set_int(23);
    cout<<ptr1.get_ptr_val()<<","<<ptr1.get_int()<<endl;
    cout<<ptr2.get_ptr_val()<<","<<ptr2.get_int()<<endl;
}

int main()
{
    cout<<"常规指针"<<endl;
    test_AHasPtr();
    cout<<"值型类"<<endl;
    test_CHasPtr();
    cout<<"智能指针"<<endl;
    test_BhasPtr();
    return 0;
}

12.重载操作符的定义

 不能重载的操作符(四个)

:: .*

.  ?:

重载操作符的注意事项

 

操作符重载

  输出操作符 >> 重载

  非成员函数 ->友元函数

  少做格式化

  输入操作符 >>重载

  处理输入操作的错误

#include <iostream>
#include <string>

using namespace std;

class Dog
{

};

class Sales_item
{
    friend ostream& operator<<(ostream& out,const Sales_item& s);
    friend istream& operator>>(istream& in,Sales_item& s);
public:
    Sales_item(const string &book,unsigned units,double price):
        isbn(book),units_sold(units),revenue(price*units)
        {

        }
    Sales_item():units_sold(0),revenue(0.0)
    {

    }
private:
    string isbn;
    unsigned units_sold;
    double revenue;
};

ostream& operator<<(ostream& out,const Sales_item& s)
{
    out<<s.isbn<<"\t"<<s.units_sold<<"\t"<<s.revenue;
    return out;
}

istream& operator>>(istream& in,Sales_item& s)
{
    double price;
    in>>s.isbn>>s.units_sold>>price;
    s.revenue = s.units_sold*price;
    if(in)
        s.revenue = s.units_sold*price;
    else
        s = Sales_item();
    return in;
}

int main()
{
    //Dog a;
    Sales_item item("0-201-78345-X",2,25.00);
    cout<<"hello"<<endl;
    cout<<item<<endl;
    cin>>item;
    cout<<item<<endl;
    cin>>item;
    cout<<item<<endl;
    return 0;
}

  为了与内置操作符保持一致,算术操作符通常产生一个新值。

  一般应使用复合赋值实现算术操作符。例如:用+=来实现+

#include <iostream>
#include <string>

using namespace std;

class Dog
{

};

class Cat
{

};

class Sales_item
{

public:
    Sales_item(const string&book,const unsigned units,const double amount):
        isbn(book),units_sold(units),revenue(amount)
        {

        }
    Sales_item& operator+=(const Sales_item&);
    Sales_item& operator-=(const Sales_item&);
    friend ostream& operator<<(ostream&,const Sales_item&);
private:
    string isbn;
    unsigned units_sold;
    double revenue;
};

Sales_item operator+(const Sales_item&,const Sales_item&);
Sales_item operator-(const Sales_item&,const Sales_item&);

Sales_item& Sales_item::operator+=(const Sales_item &rhs)
{
    units_sold += rhs.units_sold;
    revenue += rhs.revenue;
    return *this;
}

Sales_item& Sales_item::operator-=(const Sales_item& rhs)
{
    this->units_sold -= rhs.units_sold;
    this->revenue -= rhs.revenue;
    return *this;
}

Sales_item operator+(const Sales_item& lhs,const Sales_item& rhs)
{
    Sales_item ret(lhs);
    ret += rhs;
    return ret;
}

Sales_item operator-(const Sales_item& lhs,const Sales_item& rhs)
{
    Sales_item ret(lhs);
    ret -= rhs;
    return ret;
}

ostream& operator<<(ostream& out, const Sales_item& s)
{
    out<<s.isbn<<"\t"<<s.units_sold<<"\t"<<s.revenue;
    return out;
}

int main()
{
    //Dog dog;
    //Cat cat;
    Sales_item item1("0-201-12345-X",10,120.0);
    Sales_item item2("0-201-12345-X",20,200.0);
    Sales_item result = item1 + item2;
    cout<<result<<endl;
    Sales_item item3("0-201-12345-X",5,70.00);
    result += item3;
    cout<<result<<endl;

    result -= item2;
    cout<<result<<endl;
    return 0;
}

  重载关系操作符(大于小于等于)

 13.函数对象

重载函数调用操作符

函数对象:定义了调用操作符的类,其对象称为“函数对象”

一元函数对象

一元谓词

二元函数对象

二元谓词

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>

using namespace std;

struct absInt{
    int operator()(int val)
    {
        return val<0?-val:val;
    }
};

template<typename elementType>
void FuncDisplayElement(const elementType& element)
{
    cout<<element<<' ';
}


template<typename elementType>
struct DisplayElement
{
    //存储状态
    int m_nCount;

    DisplayElement()
    {
        m_nCount = 0;
    }

    void operator() (const elementType& element)
    {
        ++m_nCount;
        cout<<element<<' ';
    }
};

int main()
{
    int i = -42;
    absInt absObj;
    unsigned int ui = absObj(i);
    cout<<ui<<endl;

    vector<int> a;
    for(int n=0;n<10;++n)
        a.push_back(n);

    list<char> b;
    for(char c='a';c<'k';++c)
        b.push_back(c);

    //STL算法
    DisplayElement<int> mResult;
    mResult = for_each(a.begin(),a.end(),mResult);
    cout<<endl;
    cout<<"数量:"<<mResult.m_nCount<<endl;

    for_each(b.begin(),b.end(),DisplayElement<char>());
    cout<<endl;

    cout<<"Hello 函数对象"<<endl;
    return 0;
}

  一元函数谓词

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

template<typename numberType>
struct IsMutiple
{
    numberType m_Divisor;

    IsMutiple(const numberType& divisor)
    {
        m_Divisor = divisor;
    }

    bool operator() (const numberType& element) const
    {
        return ((element % m_Divisor)==0);
    }
};

int main()
{
    vector<int> vecIntegers;
    for(int i=33;i<=100;++i)
        vecIntegers.push_back(i);

    IsMutiple<int> a(4);

    vector<int>::iterator iElement;
    iElement = find_if(vecIntegers.begin(),vecIntegers.end(),IsMutiple<int>(4));

    if(iElement != vecIntegers.end())
    {
        cout<<"第一个4的整数倍的数是: "<<*iElement<<endl;
    }
    return 0;
}

  二元函数谓词

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

template<typename elementType>
class CMultiply
{
public:
    elementType operator() (const elementType& elem1,
                            const elementType& elem2)
                            {
                                return elem1*elem2;
                            }
};

int main()
{
    vector<int> a,b;
    for(int i=0;i<10;++i)
        a.push_back(i);

    for(int j=100;j<110;++j)
        b.push_back(j);

    vector<int> vecResult;
    vecResult.resize(10);

    transform(a.begin(),a.end(),b.begin(),vecResult.begin(),CMultiply<int>());

    for(size_t nIndex = 0;nIndex<vecResult.size();++nIndex)
        cout<<vecResult[nIndex]<<' ';
    cout<<endl;
    return 0;
}

  

#include <iostream>
#include <set>
#include <string>
#include <algorithm>

using namespace std;

class CCompareStringNoCase
{
public:
    bool operator()(const string& str1,const string& str2) const
    {
        string str1LowerCase;
        str1LowerCase.resize(str1.size());
        transform(str1.begin(),str1.end(),str1LowerCase.begin(),::tolower);

        string str2LowerCase;
        str2LowerCase.resize(str2.size());
        transform(str2.begin(),str2.end(),str2LowerCase.begin(),::tolower);

        return (str1LowerCase<str2LowerCase);
    }
};

int main()
{
    set<string,CCompareStringNoCase> name;
    name.insert("Tina");
    name.insert("jim");
    name.insert("Jack");
    name.insert("Sam");
    name.insert("hello");

    set<string,CCompareStringNoCase>::iterator iNameFound = name.find("Jim");
    if(iNameFound != name.end())
    {
        cout<<"找到了"<<*iNameFound<<endl;
    }
    else
    {
        cout<<"没找到"<<endl;
    }
    return 0;
}

  

三、C++内存管理

四、C++面向对象高级开发

 

posted @ 2023-02-07 14:53  kangobs  阅读(144)  评论(0编辑  收藏  举报