第十八章编程练习

1.下面是一个简短程序的一部分:

int main()
{
    using namespace std;
// list of double deduced from list contents
    auto q = average_list({15.4, 10.7, 9.0});
    cout << q << endl;
// list of int deduced from list contents
    cout << average_list({20, 30, 19, 17, 45, 38} ) << endl;
// forced list of double
    auto ad = average_list<double>({'A', 70, 65.33});
    cout << ad << endl;
    return 0;
}

请提供函数average_list(),让该程序变得完整。它应该是一个模板函数,其中的类型参数指定了用作函数参数的initilize_list模板的类型以及函数的返回类型。
实现:

#include <iostream>
#include <initializer_list>
using std::cout;
using std::endl;
using std::initializer_list;

template <typename T>
T average_list(initializer_list<T> i)
{
    T sum = 0;
    int count = 0;
    for (auto p = i.begin(); p <= i.end(); p++)
    {
        count++;
        sum += *p;
    }

    return  sum/count;
}

int main(void)
{

    auto q = average_list({ 15.4, 10.7, 9.0 });
    cout << q << endl;
 
    cout << average_list({ 20, 30, 19, 17, 45, 38 }) << endl;

    auto ad = average_list<double>({ 'A', 70, 65.33 });
    cout << ad << endl;


    return 0;
}

2.下面是类Cpmv的声明:

class Cpmv
{
public:
    struct Info
    {
        std::string qcode;
        std::string zcode;
    };
private:
    Info *pi;
public:
    Cpmv();
    Cpmv(std::string q, std::string z);
    Cpmv(const Cpmv & cp);
    Cpmv(Cpmv && mv);
    ~Cpmv();
    Cpmv & operator=(const Cpmv & cp);
    Cpmv & operator=(Cpmv && mv);
    Cpmv operator+(const Cpmv & obj) const;
    void Display() const;
};

函数operator+()应创建一个对象,其成员qcode和zcode有操作数的相应成员拼接而成。请提供为移动构造函数和移动赋值运算符实现移动语义的代码。编写一个使用所有这些方法的程序。为方便测试,让各个方法都显示特定的内容,以便知道它们被调用。
实现:

class Cpmv
{
public:
    struct Info
    {
        std::string qcode;
        std::string zcode;
    };
private:
    Info* pi;
public:
    Cpmv();
    Cpmv(string q, string z);
    Cpmv(const Cpmv& cp);
    Cpmv(Cpmv&& mv);
    ~Cpmv();
    Cpmv& operator=(const Cpmv& cp);
    Cpmv& operator=(Cpmv&& mv);
    Cpmv operator+(const Cpmv& obj) const;
    void Display() const;
};

int main(void)
{
    Cpmv cp1("c","c++");
    Cpmv cp2("computer", "language");
    Cpmv cp3(cp2);
    cp2 = cp1;
    Cpmv cp4(cp1 + cp2);
    
    return 0;
}

Cpmv::Cpmv()
{
    pi = nullptr;
    cout << "默认构造函数" << endl;
}

Cpmv::Cpmv(string q, string z)
{
    pi = new Info;
    pi->qcode = q;
    pi->zcode = z;
    cout << "有参构造函数" << endl;
}

Cpmv::Cpmv(const Cpmv& cp)
{
    pi = new Info;
    pi->qcode = cp.pi->qcode;
    pi->zcode = cp.pi->zcode;
    cout << "复制构造函数" << endl;
}

Cpmv::Cpmv(Cpmv&& mv)
{
    pi = mv.pi;
    mv.pi = nullptr;
    cout << "移动构造函数" << endl;
}

Cpmv::~Cpmv()
{
    delete pi;
    cout << "析构函数" << endl;
}

Cpmv& Cpmv::operator=(const Cpmv& cp)
{
    if (this == &cp)
    {
        return *this;
    }

    delete pi;
    pi = new Info;
    pi->qcode = cp.pi->qcode;
    pi->zcode = cp.pi->zcode;
    cout << "赋值运算符重载函数" << endl;
}

Cpmv& Cpmv::operator=(Cpmv&& mv)
{
    if (this == &mv)
    {
        return *this;
    }

    delete pi;
    pi = mv.pi;
    mv.pi = nullptr;
    cout << "移动赋值运算符重载函数" << endl;
}

Cpmv Cpmv::operator+(const Cpmv& obj) const
{
    return Cpmv(pi->qcode + obj.pi->qcode, pi->zcode + obj.pi->zcode);
    cout << "operator+" << endl;
}

void Cpmv::Display() const
{
    if (pi == nullptr)
    {
        cout << "pi is null" << endl;
    }
    cout << "Adress:" << pi << endl;
    cout << "qcode:" << pi->qcode << ", zcode:" << pi->zcode << endl;
    cout << "Display()" << endl;
}

3.编写并测试可变参数模板函数sum_value(),它接受任意长度的参数列表(其中包含数值,但可以是任何类型),并以long double的方式返回这些数值的和。
实现:

#include <iostream>
using std::cout;
using std::endl;

long double sum_value() { return 0; }

template <typename T, typename...Args>
long double sum_value(T value, Args...args)
{
    long double sum = (long double)value + sum_value(args...);
    return sum;
}

int main(void)
{

    cout << sum_value(1,2,3,4,5) << endl;
    cout << sum_value('a','b',2.2,3.3,5,6,7) << endl;

    return 0;
}

4.使用lambba重新编写程序清单16.5。具体地说,使用一个有名称的lambda替换函数outint(),并将函数符替换为两个匿名lambda表达式。
实现:

#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>
using std::cout;
using std::endl;
using std::list;

template<class T>
class TooBig
{
private:
	T cutoff;
public:
	TooBig(const T& t) : cutoff(t) {}
	bool operator()(const T& v) { return v > cutoff; }
};

auto OutInt = [](int n) {cout << n << " "; };

int main(void)
{
	TooBig<int> f100(100);
	int vals[10] = { 50, 100, 90, 180, 60, 210, 415, 88, 188, 201 };

	list<int> yadayada(vals, vals + 10);
	list<int> etcetera(vals, vals + 10);

	cout << "Origianl lists: " << endl;
	for_each(yadayada.begin(), yadayada.end(), OutInt);
	cout << endl;
	for_each(etcetera.begin(), etcetera.end(), OutInt);
	cout << endl;

	cout << "Trimmed lists: " << endl;
	yadayada.remove_if([](int n) {return n > 100; });
	for_each(yadayada.begin(), yadayada.end(), OutInt);
	cout << endl;
	etcetera.remove_if([](int n) { return n > 200; });
	for_each(etcetera.begin(), etcetera.end(), OutInt);
	cout << endl;

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值