//noname.h
#ifndef _NONAME_H_
#define _NONAME_H_
#include<iostream>
#include<iomanip>
#include<functional>
using namespace std;
static int flag = 0;
class noname
{
private:
static int cn;
char *str;
int num;
public:
noname() ;//=delete代表禁止该函数的调用
noname(const char &ch, const int &n);
noname(const noname &nm);//深度复制构造函数
noname(noname &&nn);//移动构造函数利用右值引用,不带const代表可以改变参数nn
~noname();
noname& operator=(const noname &nm);
noname& operator=(noname &&nn);
noname operator+(const noname &obj);
void show() const;
};
template<typename T,typename F>
auto func(T value, F f)->decltype(f(value))
{
++flag;
cout << "Flag=" << flag << "\n"
<< "Its address:" << &flag << endl;
return f(value);
}
template<typename V>
V func1(V value, function<V(V)> ft)//包装器function<返回类型(形参类型)>
{
++flag;
cout << "Flag=" << flag << "\n"
<< "Its address:" << &flag << endl;
return ft(value);
}
class f//函数对象用来测试包装器
{
private:
double data;
public:
f(const double &d) :data(d){};
double operator()(const double &v){ return data - v; }
};
class eql//用作函数符,测试lambad表达式
{
private:
int val;
public:
eql() ;
eql(const int &n) :val(n){};
virtual ~eql(){};
inline bool operator()(int &n){ return n == val; }
};
#endif //_NONAME_H_
//define.cpp
#include"noname.h"
int noname::cn = 0;
noname::noname()
{
++cn;
cout << "Using noname() construction.\n";
num = 0;
str = nullptr;
}
noname::noname(const char &ch, const int &n) :num(n)
{
++cn;
cout << "Using noname(const char &ch, const int &n) construction.\n";
str = new char[n+1];
for (int i = 0; i < n; i++)
str[i] = ch;
str[n] = '\0';
}
noname::noname(const noname &nm) :num(nm.num)
{
++cn;
cout << "Using noname(const noname &nm) construction.\n";
str = new char[nm.num+1];
for (int i = 0; i < nm.num; i++)
str[i] = nm.str[i];
str[nm.num] = '\0';
}
noname::noname(noname &&nn)
{
++cn;
cout << "Using noname(noname &&nn) construction.\n";
num = nn.num;
str = nn.str;//直接传递地址
nn.str = nullptr;
nn.num = 0;
}
noname::~noname()
{
delete[] str;
--cn;
}
noname& noname::operator=(const noname &nm)
{
cout << "Using operator=(const noname &nm).\n";
if (this == &nm)
return *this;
delete[] str;
num = nm.num;
str = new char[nm.num+1];
for (int i = 0; i < nm.num; i++)
str[i] = nm.str[i];
str[nm.num] = '\0';
return *this;
}
noname& noname::operator=(noname &&nn)
{
cout << "Using operator=(const noname &&nn)." << endl;
if (this == &nn)
return *this;
delete[] str;
num = nn.num;
str = nn.str;
nn.str = nullptr;
nn.num = 0;
return *this;
}
noname noname::operator+(const noname &obj)
{
noname temp;
int i, j;
temp.num = num + obj.num;//两个结束符'\0'只需加1个
temp.str = new char[temp.num+1];
for (i = 0; i < num; i++)
temp.str[i] = str[i];
for (j = 0; j < obj.num;j++)
temp.str[i++] = obj.str[j];
temp.str[i] = '\0';
return temp;
}
void noname::show() const
{
cout.setf(ios_base::right, ios_base::adjustfield);
cout << setw(8) << "Num:" << setprecision(3) << num << "\n"
<< setw(8) << "String:" << str << endl;
}
eql::eql()
{
val = 0;
}
//main.cpp
#include<iostream>
#include<cstdlib>
#include<functional>
#include<string>
#include<algorithm>
#include<ctime>
#include<vector>
#include"noname.h"
#include"windows.h"
using namespace std;
static int k = 0;
double f1(const double &d){ return 2 * d; }
void display(const int &v);
int Rand(){ return rand() % 10; }
template<typename T,typename...Args>
void out(const T &one,const Args&...args)
{
cout << one << ", ";
out(args...);
}
//对于可变参数模板先提供一个整体模板,然后在整体内递归
//同时不要忘了提供一个元素时候的单独模板
template<typename T>
void out(const T &another)
{
cout << another << endl;
}
int main()
{
noname nameA('Q', 5),nameB('P',3);
noname nameC(nameA),nameD(nameA+nameB);
cout << "nameC:" << endl;
nameC.show();
cout << "nameD:" << endl;
nameD.show();
noname nameE, nameF;
nameE = nameD;
nameF = nameC + nameD;
cout << "nameE:" << endl;
nameE.show();
cout << "nameF:" << endl;
nameF.show();
srand(time(0));
vector<int>vec(30);
generate(vec.begin(), vec.end(), Rand);
for_each(vec.begin(), vec.end(), display);
eql eq5(5);
int cnt5 = count_if(vec.begin(), vec.end(), eq5);
int cnt8 = count_if(vec.begin(), vec.end(), [](int x){return x == 8; });
cout << "The number of equal to 5 is:" << cnt5 << endl;
cout << "The number of equal to 10 is:" << cnt8 << endl;
using non = function<double(double)>;
non f_1 = f1, f_2 = f(9.6), f_3 = [](double x){return x*5.2; };
cout << "Using f1:\n" << func(3, f_1) << endl;
cout << "Using class f:\n" << func(3, f_2) << endl;
cout << "Using Lambad experssion:\n" << func(3, f_3) << endl;
cout << "Using template function:\n" << func1<double>(4.2, [](double x){return x*x; });
cout << "\nNow,next to introduce variadic template."<<endl;
cout << "Show two arguments:";
out("I love china", 99);
cout << "Show four arguments:";
out("I love china", 99,string("I also love my hometown"),'!');
system("pause");
return 0;
}
void display(const int &v)
{
cout.setf(ios_base::right, ios_base::adjustfield);
cout << setw(3) << v;
k++;
if (k % 5 == 0)
cout << endl;
}
程序运行结果如下
Using noname(const char &ch, const int &n) construction.
Using noname(const char &ch, const int &n) construction.
Using noname(const noname &nm) construction.
Using noname() construction.
Using noname(noname &&nn) construction.
nameC:
Num:5
String:QQQQQ
nameD:
Num:8
String:QQQQQPPP
Using noname() construction.
Using noname() construction.
Using operator=(const noname &nm).
Using noname() construction.
Using noname(noname &&nn) construction.
Using operator=(const noname &&nn).
nameE:
Num:8
String:QQQQQPPP
nameF:
Num:13
String:QQQQQQQQQQPPP
0 1 5 0 4
8 5 2 8 1
3 3 7 4 2
0 9 2 8 5
0 3 4 2 8
4 1 2 1 3
The number of equal to 5 is:3
The number of equal to 10 is:4
Flag=1
Its address:00CDE6A8
Using f1:
6
Flag=2
Its address:00CDE6A8
Using class f:
6.6
Flag=3
Its address:00CDE6A8
Using Lambad experssion:
15.6
Flag=4
Its address:00CDE6A8
Using template function:
17.6
Now,next to introduce variadic template.
Show two arguments:I love china, 99
Show four arguments:I love china, 99, I also love my hometown, !
请按任意键继续. . .