C++ Primer Plus(第六版)第18章 探讨新C++标准

rvref.cpp  

// rvref.cpp -- simple uses of rvalue references
#include <iostream>

inline double f(double tf) {return 5.0*(tf-32.0)/9.0;};
int main()
{
    using namespace std;
    double tc = 21.5;
    double && rd1 = 7.07;
    double && rd2 = 1.8 * tc + 32.0;
    double && rd3 = f(rd2);
    cout << " tc value and address: " << tc <<", " << &tc << endl;
    cout << "rd1 value and address: " << rd1 <<", " << &rd1 << endl;
    cout << "rd2 value and address: " << rd2 <<", " << &rd2 << endl;
    cout << "rd3 value and address: " << rd3 <<", " << &rd3 << endl;
    // cin.get();
    return 0;
}

执行结果:

tc value and address: 21.5, 00AFF768
rd1 value and address: 7.07, 00AFF74C
rd2 value and address: 70.7, 00AFF730
rd3 value and address: 21.5, 00AFF714

useless.cpp 

// useless.cpp -- an otherwise useless class with move semantics
#include <iostream>
using namespace std;

// interface
class Useless
{
private:
    int n;          // number of elements
    char * pc;      // pointer to data
    static int ct;  // number of objects
    void ShowObject() const;
public:
    Useless();
    explicit Useless(int k);
    Useless(int k, char ch);
    Useless(const Useless & f); // regular copy constructor
    Useless(Useless && f);      // move constructor
    ~Useless();
    Useless operator+(const Useless & f)const;
// need operator=() in copy and move versions
    void ShowData() const;
};

// implementation
int Useless::ct = 0;

Useless::Useless()
{
    ++ct;
    n = 0;
    pc = nullptr;
    cout << "default constructor called; number of objects: " << ct << endl;
    ShowObject();
}

Useless::Useless(int k) : n(k)
{
    ++ct; 
    cout << "int constructor called; number of objects: " << ct << endl;
    pc = new char[n];
    ShowObject();
}

Useless::Useless(int k, char ch) : n(k)
{
    ++ct;
    cout << "int, char constructor called; number of objects: " << ct << endl;
    pc = new char[n];
    for (int i = 0; i < n; i++)
        pc[i] = ch;
    ShowObject();
}

Useless::Useless(const Useless & f): n(f.n) 
{
    ++ct;
    cout << "copy const called; number of objects: " << ct << endl;
    pc = new char[n];
    for (int i = 0; i < n; i++)
        pc[i] = f.pc[i];
    ShowObject();
}

Useless::Useless(Useless && f): n(f.n) 
{
    ++ct;
    cout << "move constructor called; number of objects: " << ct << endl;
    pc = f.pc;       // steal address
    f.pc = nullptr;  // give old object nothing in return
    f.n = 0;
    ShowObject();
}

Useless::~Useless()
{
    cout << "destructor called; objects left: " << --ct << endl;
    cout << "deleted object:\n";
    ShowObject();
    delete [] pc;
}

Useless Useless::operator+(const Useless & f)const
{
    cout << "Entering operator+()\n";
    Useless temp = Useless(n + f.n);
    for (int i = 0; i < n; i++)
        temp.pc[i] = pc[i];
    for (int i = n; i < temp.n; i++)
        temp.pc[i] = f.pc[i - n];
    cout << "temp object:\n";
    cout << "Leaving operator+()\n";
    return temp;
}

void Useless::ShowObject() const
{ 
    cout << "Number of elements: " << n;
    cout << " Data address: " << (void *) pc << endl;
}

void Useless::ShowData() const
{
    if (n == 0)
        cout << "(object empty)";
    else
        for (int i = 0; i < n; i++)
            cout << pc[i];
    cout << endl;
}

// application
int main()
{
    {
        Useless one(10, 'x');
        Useless two = one;          // calls copy constructor
        Useless three(20, 'o');
        Useless four(one + three);  // calls operator+(), move constructor
        cout << "object one: ";
        one.ShowData();
        cout << "object two: ";
        two.ShowData();
        cout << "object three: ";
        three.ShowData();
        cout << "object four: ";
        four.ShowData();
    }
    // cin.get();
}

执行结果:

int, char constructor called; number of objects: 1
Number of elements: 10 Data address: 00A46038
copy const called; number of objects: 2
Number of elements: 10 Data address: 00A45EB0
int, char constructor called; number of objects: 3
Number of elements: 20 Data address: 00A49380
Entering operator+()
int constructor called; number of objects: 4
Number of elements: 30 Data address: 00A4CEC8
temp object:
Leaving operator+()
move constructor called; number of objects: 5
Number of elements: 30 Data address: 00A4CEC8
destructor called; objects left: 4
deleted object:
Number of elements: 0 Data address: 00000000
object one: xxxxxxxxxx
object two: xxxxxxxxxx
object three: oooooooooooooooooooo
object four: xxxxxxxxxxoooooooooooooooooooo
destructor called; objects left: 3
deleted object:
Number of elements: 30 Data address: 00A4CEC8
destructor called; objects left: 2
deleted object:
Number of elements: 20 Data address: 00A49380
destructor called; objects left: 1
deleted object:
Number of elements: 10 Data address: 00A45EB0
destructor called; objects left: 0
deleted object:
Number of elements: 10 Data address: 00A46038

stdmove.cpp 

// stdmove.cpp -- using std::move()
#include <iostream>
#include <utility>
// use the following for g++4.5
// #define nullptr 0
// interface
class Useless
{
private:
    int n;          // number of elements
    char * pc;      // pointer to data
    static int ct;  // number of objects
    void ShowObject() const;
public:
    Useless();
    explicit Useless(int k);
    Useless(int k, char ch);
    Useless(const Useless & f); // regular copy constructor
    Useless(Useless && f);      // move constructor
    ~Useless();
    Useless operator+(const Useless & f)const;
    Useless & operator=(const Useless & f); // copy assignment
    Useless & operator=(Useless && f);      // move assignment 
    void ShowData() const;
};

// implementation
int Useless::ct = 0;

Useless::Useless()
{
    ++ct;
    n = 0;
    pc = nullptr;
 }

Useless::Useless(int k) : n(k)
{
    ++ct; 
    pc = new char[n];
}

Useless::Useless(int k, char ch) : n(k)
{
    ++ct;
    pc = new char[n];
    for (int i = 0; i < n; i++)
        pc[i] = ch;
}

Useless::Useless(const Useless & f): n(f.n) 
{
    ++ct;
    pc = new char[n];
    for (int i = 0; i < n; i++)
        pc[i] = f.pc[i];
}

Useless::Useless(Useless && f): n(f.n) 
{
    ++ct;
    pc = f.pc;       // steal address
    f.pc = nullptr;  // give old object nothing in return
    f.n = 0;
}

Useless::~Useless()
{
    delete [] pc;
}

Useless & Useless::operator=(const Useless & f)  // copy assignment
{
    std::cout << "copy assignment operator called:\n";
    if (this == &f)
        return *this;
    delete [] pc;
    n = f.n;
    pc = new char[n];
    for (int i = 0; i < n; i++)
        pc[i] = f.pc[i];
    return *this;
}

Useless & Useless::operator=(Useless && f)       // move assignment
{
    std::cout << "move assignment operator called:\n";
    if (this == &f)
        return *this;
    delete [] pc;
    n = f.n;
    pc = f.pc;
    f.n = 0;
    f.pc = nullptr;
    return *this;
}

Useless Useless::operator+(const Useless & f)const
{
    Useless temp = Useless(n + f.n);
    for (int i = 0; i < n; i++)
        temp.pc[i] = pc[i];
    for (int i = n; i < temp.n; i++)
        temp.pc[i] = f.pc[i - n];
    return temp;
}

void Useless::ShowObject() const
{ 
    std::cout << "Number of elements: " << n;
    std::cout << " Data address: " << (void *) pc << std::endl;
}

void Useless::ShowData() const
{
    if (n == 0)
        std::cout << "(object empty)";
    else
        for (int i = 0; i < n; i++)
            std::cout << pc[i];
    std::cout << std::endl;
}

// application
int main()
{
    using std::cout;
    {
        Useless one(10, 'x');
        Useless two = one +one;   // calls move constructor
        cout << "object one: ";
        one.ShowData();
        cout << "object two: ";
        two.ShowData();
        Useless three, four;
        cout << "three = one\n";
        three = one;              // automatic copy assignment
        cout << "now object three = ";
        three.ShowData();
        cout << "and object one = ";
        one.ShowData();
        cout << "four = one + two\n";
        four = one + two;         // automatic move assignment
        cout << "now object four = ";
        four.ShowData();
        cout << "four = move(one)\n";
        four = std::move(one);    // forced move assignment
        cout << "now object four = ";
        four.ShowData();
        cout << "and object one = ";
        one.ShowData();
    }
     std::cin.get();
}

执行结果:

object one: xxxxxxxxxx
object two: xxxxxxxxxxxxxxxxxxxx
three = one
copy assignment operator called:
now object three = xxxxxxxxxx
and object one = xxxxxxxxxx
four = one + two
move assignment operator called:
now object four = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
four = move(one)
move assignment operator called:
now object four = xxxxxxxxxx
and object one = (object empty)

lambda0.cpp 

// lambda0.cpp -- using lambda expressions
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
const long Size1 = 39L;
const long Size2 = 100*Size1;
const long Size3 = 100*Size2;

bool f3(int x) {return x % 3 == 0;}
bool f13(int x) {return x % 13 == 0;}

int main()
{
    using std::cout;
    std::vector<int> numbers(Size1);

    std::srand(std::time(0));
    std::generate(numbers.begin(), numbers.end(), std::rand);

// using function pointers
    cout << "Sample size = " << Size1 << '\n';

    int count3 = std::count_if(numbers.begin(), numbers.end(), f3);
    cout << "Count of numbers divisible by 3: " << count3 << '\n';
    int count13 = std::count_if(numbers.begin(), numbers.end(), f13);
    cout << "Count of numbers divisible by 13: " << count13 << "\n\n";

// increase number of numbers
    numbers.resize(Size2);
    std::generate(numbers.begin(), numbers.end(), std::rand);
    cout << "Sample size = " << Size2 << '\n';
// using a functor
    class f_mod
    {
    private:
        int dv;
    public:
        f_mod(int d = 1) : dv(d) {}
        bool operator()(int x) {return x % dv == 0;}
    };

    count3 = std::count_if(numbers.begin(), numbers.end(), f_mod(3));
    cout << "Count of numbers divisible by 3: " << count3 << '\n';
    count13 = std::count_if(numbers.begin(), numbers.end(), f_mod(13));
    cout << "Count of numbers divisible by 13: " << count13 << "\n\n";

// increase number of numbers again
    numbers.resize(Size3);
    std::generate(numbers.begin(), numbers.end(), std::rand);
    cout << "Sample size = " << Size3 << '\n';
// using lambdas
    count3 = std::count_if(numbers.begin(), numbers.end(),
             [](int x){return x % 3 == 0;});
    cout << "Count of numbers divisible by 3: " << count3 << '\n';
    count13 = std::count_if(numbers.begin(), numbers.end(),
              [](int x){return x % 13 == 0;});
    cout << "Count of numbers divisible by 13: " << count13 << '\n';

    // std::cin.get();
    return 0;
}

执行结果:

Sample size = 39
Count of numbers divisible by 3: 15
Count of numbers divisible by 13: 0

Sample size = 3900
Count of numbers divisible by 3: 1283
Count of numbers divisible by 13: 275

Sample size = 390000
Count of numbers divisible by 3: 130022
Count of numbers divisible by 13: 29969

lambda1.cpp  

// lambda1.cpp -- use captured variables
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
const long Size = 390000L;

int main()
{
    using std::cout;
    std::vector<int> numbers(Size);

    std::srand(std::time(0));
    std::generate(numbers.begin(), numbers.end(), std::rand);
    cout << "Sample size = " << Size << '\n';
// using lambdas
    int count3 = std::count_if(numbers.begin(), numbers.end(), 
		      [](int x){return x % 3 == 0;});
    cout << "Count of numbers divisible by 3: " << count3 << '\n';
    int count13 = 0;
    std::for_each(numbers.begin(), numbers.end(),
         [&count13](int x){count13 += x % 13 == 0;});
    cout << "Count of numbers divisible by 13: " << count13 << '\n';
// using a single lambda
    count3 = count13 = 0;
    std::for_each(numbers.begin(), numbers.end(),
         [&](int x){count3 += x % 3 == 0; count13 += x % 13 == 0;});
    cout << "Count of numbers divisible by 3: " << count3 << '\n';
    cout << "Count of numbers divisible by 13: " << count13 << '\n';

    // std::cin.get();
    return 0;
}

执行结果:

Sample size = 390000
Count of numbers divisible by 3: 129765
Count of numbers divisible by 13: 30268
Count of numbers divisible by 3: 129765
Count of numbers divisible by 13: 30268

somedefs.h 

// somedefs.h
#include <iostream>

template <typename T, typename F>
  T use_f(T v, F f)
  {
      static int count = 0;
      count++;
      std::cout << "use_f count = " << count
		        << ", &count = " << &count << endl;
      return f(v);
  }

  class Fp
  {
  private:
      double z_;
  public:
      Fp(double z = 1.0) : z_(z) {}
      double operator()(double p) { return z_*p; }
  };

  class Fq
  {
  private:
      double z_;
  public:
      Fq(double z = 1.0) : z_(z) {}
      double operator()(double q) { return z_+ q; }
  };·

callable.cpp 

// callable.cpp -- callable types and templates
#include <iostream>
#include"somedefs.h"
using namespace std;

double dub(double x) { return 2.0 * x; }
double square(double x) { return x * x; }

int main()
{
	double y = 1.21;
	cout << "Function pointer dub:\n";
	cout << "  " << use_f(y, dub) << endl;
	cout << "Function pointer sqrt:\n";
	cout << "  " << use_f(y, square) << endl;
	cout << "Function object Fp:\n";
	cout << "  " << use_f(y, Fp(5.0)) << endl;
	cout << "Function object Fq:\n";
	cout << "  " << use_f(y, Fq(5.0)) << endl;
	cout << "Lambda expression 1:\n";
	cout << "  " << use_f(y, [](double u) {return u * u; }) << endl;
	cout << "Lambda expresson 2:\n";
	cout << "  " << use_f(y, [](double u) {return u + u / 2.0; }) << endl;

	cin.get();
	return 0;
}

执行结果:

Function pointer dub:
use_f count = 1,count = 0010C140
  2.42
Function pointer sqrt:
use_f count = 2,count = 0010C140
  1.4641
Function object Fp:
use_f count = 1,count = 0010C144
  6.05
Function object Fq:
use_f count = 1,count = 0010C148
  6.21
Lambda expression 1:
use_f count = 1,count = 0010C14C
  1.4641
Lambda expresson 2:
use_f count = 1,count = 0010C150
  1.815

 wrapped0.cpp

// wrapped0.cpp  -- using a function wrapper
#include "somedefs.h"
#include <iostream>
#include <math.h>
#include <functional>

double dub(double x) { return 2.0 * x; }
double sqaure(double x) { return x * x; }
int main()
{
	using std::cout;
	using std::endl;
	using std::function;
	typedef function<double(double)> fdd;
	double y = 1.21;
	function<double(double)> ef1 = dub;
	function<double(double)> ef2 = sqaure;
	function<double(double)> ef3 = Fq(10.0);
	function<double(double)> ef4 = Fp(10.0);
	function<double(double)> ef5 = [](double u) {return u * u; };
	function<double(double)> ef6 = [](double u) {return u + u / 2.0; };
	cout << use_f(y, function<double(double)>(dub)) << endl;
	cout << use_f(y, fdd(sqaure)) << endl;
	cout << use_f(y, ef3) << endl;
	cout << use_f(y, ef4) << endl;
	cout << use_f(y, ef5) << endl;
	cout << use_f(y, ef6) << endl;

	std::cin.get();
	return 0;
}

执行结果:

use_f count = 1,count = 00A834E0
2.42
use_f count = 2,count = 00A834E0
1.4641
use_f count = 3,count = 00A834E0
11.21
use_f count = 4,count = 00A834E0
12.1
use_f count = 5,count = 00A834E0
1.4641
use_f count = 6,count = 00A834E0
1.815

 wrapped2.cpp 

//wrapped1.cpp -- using a function wrapper as an argument
#include <iostream>
#include <math.h>
#include <functional>
#include"somedefs.h"
using namespace std;


double dub(double x) { return 2.0 * x; }
double sqaure(double x) { return x * x; }

int main()
{
	double y = 1.21;
	function<double(double)> ef1 = dub;
	function<double(double)> ef2 = sqaure;
	function<double(double)> ef3 = Fq(10.0);
	function<double(double)> ef4 = Fp(10.0);
	function<double(double)> ef5 = [](double u) {return u * u; };
	function<double(double)> ef6 = [](double u) {return u + u / 2.0; };
	cout << "Function pointer dub:\n";
	cout << "  " << use_f(y, ef1) << endl;
	cout << "Function pointer sqrt:\n";
	cout << "  " << use_f(y, ef2) << endl;
	cout << "Function object Fp:\n";
	cout << "  " << use_f(y, ef3) << endl;
	cout << "Function object Fq:\n";
	cout << "  " << use_f(y, ef4) << endl;
	cout << "Lambda expression 1:\n";
	cout << "  " << use_f(y, ef5) << endl;
	cout << "Lambda expression 2:\n";
	cout << "  " << use_f(y, ef6) << endl;
	// cin.get();
	return 0;
}

执行结果:

Function pointer dub:
use_f count = 1,count = 00D134E0
  2.42
Function pointer sqrt:
use_f count = 2,count = 00D134E0
  1.4641
Function object Fp:
use_f count = 3,count = 00D134E0
  11.21
Function object Fq:
use_f count = 4,count = 00D134E0
  12.1
Lambda expression 1:
use_f count = 5,count = 00D134E0
  1.4641
Lambda expression 2:
use_f count = 6,count = 00D134E0
  1.815

wrapped2.cpp 

// wrapped2.cpp -- callable types and templates
#include <iostream>
#include <math.h>
#include <functional>
#include"somedefs.h"
using namespace std;

double dub(double x) { return 2.0 * x; }
double sqaure(double x) { return x * x; }

int main()
{
	double y = 1.21;
	cout << "Function pointer dub:\n";
	cout << "  " << use_f<double>(y, dub) << endl;
	cout << "Function pointer sqrt:\n";
	cout << "  " << use_f<double>(y, sqaure) << endl;
	cout << "Function object Fp:\n";
	cout << "  " << use_f<double>(y, Fp(5.0)) << endl;
	cout << "Function object Fq:\n";
	cout << "  " << use_f<double>(y, Fq(5.0)) << endl;
	cout << "Lambda expression 1:\n";
	cout << "  " << use_f<double>(y, [](double u) {return u * u; }) << endl;
	cout << "Lambda expression 2:\n";
	cout << "  " << use_f<double>(y, [](double u) {return u + u / 2.0; }) << endl;

	cin.get();
	return 0;
}

执行结果:

Function pointer dub:
use_f count = 1,count = 008F34E0
  2.42
Function pointer sqrt:
use_f count = 2,count = 008F34E0
  1.4641
Function object Fp:
use_f count = 1,count = 008F34F0
  6.05
Function object Fq:
use_f count = 1,count = 008F34F4
  6.21
Lambda expression 1:
use_f count = 1,count = 008F3814
  1.4641
Lambda expression 2:
use_f count = 1,count = 008F3818
  1.815

variadic1.cpp 

//variadic1.cpp -- using recursion to unpack a parameter pack
#include <iostream>
#include <string>
// definition for 0 parameters -- terminating call
void show_list3() {}

// definition for 1 or more parameters
template<typename T, typename... Args>
void show_list3(T value, Args... args)
{
	std::cout << value << ", ";
	show_list3(args...);
}

int main()
{
	int n = 14;
	double x = 2.71828;
	std::string mr = "Mr. String objects!";
	show_list3(n, x);
	show_list3(x*x, '!', 7, mr);
	return 0;
}

执行结果:

14, 2.71828, 7.38905, !, 7, Mr. String objects!,

variadic2.cpp 

// variadic2.cpp
#include <iostream>
#include <string>

// definition for 0 parameters
void show_list() {}

// definition for 1 parameter
template<typename T>
void show_list(const T& value)
{
    std::cout << value << '\n';
}

// definition for 2 or more parameters
template<typename T, typename... Args>
void show_list(const T& value, const Args&... args)
{
    std::cout << value << ", ";
    show_list(args...); 
}

int main()
{
    int n = 14;
    double x = 2.71828;
    std::string mr = "Mr. String objects!";
    show_list(n, x);
    show_list(x*x, '!', 7, mr);
    return 0;
}

执行结果:

14, 2.71828
7.38905, !, 7, Mr. String objects!

lexcast.cpp 

// lexcast.cpp -- simple cast from float to string
#include <iostream>
#include <string>
#include "boost/lexical_cast.hpp"
int main()
{
	using namespace std;
	cout << "Enter your weight: ";
	float weight;
	cin >> weight;
	string gain = "A 10% increase raises ";
	string wt = boost::lexical_cast<string>(weight);
	gain = gain + wt + " to ";  // string operator+()
	weight = 1.1 * weight;
	gain = gain + boost::lexical_cast<string>(weight) + ".";
	cout << gain << endl;
	return 0;
}

执行需要安装boost库

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长沙有肥鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值