临时对象的产生
- 临时对象也叫做 无名对象,(使用pass by value的方式会引发copy的操作,于是产生一个临时的对象),造成效率的负担,但是可以可以制造一些临时对象
- 在型别的后面 直接加上() 并可以指定初始数值,相当于调用型别的构造函数,但是不指定对象的名称
- 临时对象一般常用于 仿函数和算法搭配上
- 代码如下所示 print<int>的临时对象被传入 for_each函数中起作用,当for_each结束的时候,临时对象结束了他的生命
#include <vector>
#include <iostream>
#include <algorithm>template<typename T>
class print{
public:void operator()(const T&elem){ //operator 重载()std::cout <<elem << " ";}
};void print_function(int value){std::cout <<value << " ";
}int main(){int ia[6] = {0,1,2,3,4,5};std::vector<int>iv{ia,ia+6};std::for_each(iv.begin(),iv.end(),print<int>()); //使用模板类的方式
// std::for_each(iv.begin(),iv.end(), print_function);}
静态常量整数成员在class内部 直接初始化
#include <vector>
#include <iostream>
#include <algorithm>template<typename T>
class print{
public:void operator()(const T&elem){ //operator 重载()std::cout <<elem << " ";}
};void print_function(int value){std::cout <<value << " ";
}template <typename T>
class testClass{
public:static const T static_const_data_i = 5;static T static_data_i;
};//对于模板中使用static变量初始化,这段代码不能省略
template<typename T>
T testClass<T>::static_data_i = 0;int main(){testClass<int>temp;temp.static_data_i = 9;std::cout << testClass<int>::static_data_i << std::endl;std::cout << testClass<int>::static_const_data_i << std::endl;
}
递增/递减/解除引用 的运算符重载写法
#include <vector>
#include <iostream>
#include <algorithm>class INT{friend std::ostream& operator<< (std::ostream& os,const INT& i);
public:INT(int i):m_i(i){};//prefix:increment and then fetchINT& operator++(){++(this->m_i); //随着class的不同,这一行有不同的操作return *this;}const INT operator++(int){INT temp = *this;++(*this);return temp;}INT& operator--(){--(this->m_i);return *this;}const INT operator--(int){INT temp = *this;--(*this);return temp;}int & operator*() const{return (int &)m_i;}
private:int m_i;
};std::ostream& operator<<(std::ostream& os,const INT& i){os << '[' << i.m_i << ']' << " ";return os;
}int main(){INT I(5);std::cout << I++ ;// [5]std::cout << ++I; // [7]std::cout << I--; // [7]std::cout << --I; // [5]std::cout << *I; // 5
}
前闭后开 区间表示法
- STL算法需要使用一对迭代器(泛型指针)表示 区间,也就是操作的的范围,使用[first.,last)来表示;实际的范围是first 开始 到 last-1结束
- last指代的是 最后一个元素的下一个位置
- 使用的是 偏移一格 的标示法
template<class InputIterator,class T>
InputIterator find(InputIterator first,InputIterator last,const T& value){while(first != last && *first != value){++first;}return value;
}template<class InputIterator,class Function>
Function for_each(InputIterator first,InputIterator last,Function f){for (; first != last; ++first) {f(*first);}return f;
}
函数回调 操作符( function call)
- 函数调用操作(也就是左括号和右括号) 也可以被重载
- STL算法 提供了两个版本,一个用于一般情况(比如按照递增序列进行排序) ;一个用于特殊情况(按照用户指定的规则进行排序);用户指定的规则 是通过函数进行制定的
- 先前 C语言时代 如果想将函数作为参数进行传递 只能使用函数指针的方式
#include <vector>
#include <iostream>
#include <algorithm>int fcmp(const void* elem1,const void* elem2){const int* i1 = (const int*) elem1;const int* i2 = (const int*) elem2;if (*i1 < *i2){return -1;}else if(*i1 == *i2){return 0;}elsereturn 1;}int main(){int ia[10] = {32,92,67,58,10,4,25,52,59,54};for (int i = 0; i < 10; ++i) {std::cout << ia[i] << " ";}qsort(ia,sizeof(ia)/sizeof (int), sizeof (int),fcmp);std::cout << std::endl;for (int i = 0; i < 10; ++i) {std::cout << ia[i] << " ";}
}
- 函数指针有缺陷 无法维持自己的状态 也无法达到组件技术中的 可适配性,也就是无法再将 某些装饰条件 加诸其上而改变其状态
- 因此STL使用仿函数的形式实现了所谓的策略,仿函数类似于函数,比如针对某个类的进行operator()重载 就成为了仿函数,如果需要将其转换为可配接的仿函数需要额外的努力
- 这个例子 缺乏 可配接能力 的体现 将在第8章 详述
#include <vector>
#include <iostream>
#include <algorithm>//由于将operator()重载了 因此plus成为了一个仿函数
template <class T>
struct plus{T operator()(const T& x,const T& y)const{return x+y;}
};//由于将operator()重载了 因此minus成为了一个仿函数
template <class T>
struct minus{T operator()(const T& x,const T& y)const{return x-y;}
};int main(){//产生仿函数对象plus<int>plus_obj;minus<int>minus_obj;//以下使用仿函数就像使用一般函数一样std::cout << plus_obj(3,67) << std::endl;std::cout << minus_obj(67,3) << std::endl;//以下直接产生函数的临时对象(第一对小括号) 并进行调用(第二队小括号)//使用括号产生临时对象std::cout << plus<int>()(3,67) <<std::endl;std::cout << minus<int>()(67,3) << std::endl;
}
参考链接
- c++类模板遇上static关键字_宿罪的博客-CSDN博客_static 模板
- c++中ostream类的超详细说明 - 知乎