18.11 复习题
1.使用大括号括起的初始化列表语法重写下述代码。重写后的代码不应使用数组ar:
class Z200
{
private:
int j;
char ch;
double z;
public:
Z200(int jv, char chv, double zv) : j(jv), ch(chv), z(zv){}
};
int main(int argc, char* argv[])
{
double x = 8.8;
string s = "What a bracing effect!";
int k(99);
Z200 zip(200, 'Z', 0.675);
vector<int> ai(5);
int ar[5] = { 3, 9, 4, 7, 1 };
for (auto pt = ai.begin(), int i = 0; pt != ai.end(); ++pt, ++i)
{
*pt = ai[i];
}
return 0;
}
修改后:
class Z200
{
private:
int j;
char ch;
double z;
public:
Z200(int jv, char chv, double zv) : j(jv), ch(chv), z(zv){}
};
int main(int argc, char* argv[])
{
double x = { 8.8 };
string s = { "What a bracing effect!" };
int k{ 99 };
Z200 zip{ 200, 'Z', 0.675};
vector<int> ai = { 3, 9, 4, 7, 1 };
return 0;
}
2.在下述简短的程序中,那些函数调用不对?为什么?对于合法的函数调用,指出其引用参数指向的是什么。
#include <iostream>
using namespace std;
double up(double x) { return 2.0 * x; }
void r1(const double& rx){ cout << rx << endl; }
void r2(double & rx){ cout << rx << endl; }
void r3(double &&rx){ cout << rx << endl; }
int main(int argc, char* argv[])
{
double w = 10.0;
r1(w);
r1(w + 1);
r1(up(w));
r2(w);
r2(w + 1);
r2(up(w));
r3(w);
r3(w + 1);
r3(up(w));
return 0;
}
答案:
//
// main.cpp
// HelloWorld
//
// Created by feiyin001 on 17/01/04.
// Copyright (c) 2016年 Fable. All rights reserved.
//
#include <iostream>
using namespace std;
double up(double x) { return 2.0 * x; }
void r1(const double& rx){ cout << rx << endl; }
void r2(double & rx){ cout << rx << endl; }
void r3(double &&rx){ cout << rx << endl; }
int main(int argc, char* argv[])
{
double w = 10.0;
r1(w); //正确,指向w
r1(w + 1); //正确,指向临时对象
r1(up(w)); //正确,指向up返回的临时对象
r2(w); //正确,指向w
r2(w + 1); //不正确,不能对临时对象进行引用
r2(up(w)); //不正确,不能对临时对象进行引用
r3(w); //不正确,只能对临时对象使用
r3(w + 1); //正确,指向临时对象
r3(up(w)); //正确,指向临时对象
return 0;
}
3.a.下述简短的程序显示什么?为什么?
#include <iostream>
using namespace std;
double up(double x) { return 2.0 * x; }
void r1(const double& rx){ cout << "const double & rx" << endl; }
void r1(double & rx){ cout << "double & rx" << endl; }
int main(int argc, char* argv[])
{
double w = 10.0;
r1(w); //
r1(w + 1); //
r1(up(w)); //
return 0;
}
r1(w);
//double & rx
r1(w + 1); //const double & rx
r1(up(w)); //const double & rx
临时对象属于右值,不能使用普通的引用。
b.下述简短的程序显示什么?为什么?
#include <iostream>
using namespace std;
double up(double x) { return 2.0 * x; }
void r1(double& rx){ cout << "double & rx" << endl; }
void r1(double&& rx){ cout << "double && rx" << endl; }
int main(int argc, char* argv[])
{
double w = 10.0;
r1(w);
r1(w + 1);
r1(up(w));
return 0;
}
r1(w);
//double & rx
r1(w + 1); //double && rx
r1(up(w)); //double && rx
右值匹配移动引用。
c.下述简短的程序显示什么?为什么?
#include <iostream>
using namespace std;
double up(double x) { return 2.0 * x; }
void r1(const double& rx){ cout << "const double & rx" << endl; }
void r1(double&& rx){ cout << "double && rx" << endl; }
int main(int argc, char* argv[])
{
double w = 10.0;
r1(w);
r1(w + 1);
r1(up(w));
return 0;
}
r1(w); //const double & rx
r1(w + 1); //double && rx
r1(up(w)); //double && rx
临时对象匹配了右值引用,左值只能匹配const引用了。
4.哪些成员函数是特殊的成员函数?它们特殊的原因是什么?
构造函数
复制构造函数
移动复制构造函数
复制赋值运算符
移动赋值运算符
析构函数
这些函数,编译器根据情况自动提供他们的默认版本。
5.假设Fizzle类只有如下所示的数据成员:
class Fizzle
{
private:
double bubbles[4000];
}
为什么不适合给这个类定义移动构造函数?要让这个类适合定义移动构造函数,应如何修改存储4000个double值的方式?
bubbles自动存储变量,而不是动态变量。
class Fizzle
{
private:
double* bubbles;
}
6.修改下述简短的程序,使其使用lambda表达式而不是f1()。请不要修改show2()。
#include <iostream>
using namespace std;
template<typename T>
void show2(double x, T&fp){ cout << x << " -> " << fp(x) << '\n'; }
double f1(double x) { return 8 * x + 32; }
int main(int argc, char* argv[])
{
show2(18.0, f1);
return 0;
}
答案:
#include <iostream>
using namespace std;
template<typename T>
void show2(double x, T&fp){ cout << x << " -> " << fp(x) << '\n'; }
int main(int argc, char* argv[])
{
show2(18.0, [](double x){ return 8 * x + 32; });
return 0;
}
7.修改下述简短而丑陋的程序,使其使用lambda表达式而不是函数符Adder。请不要修改sum()。
//
// main.cpp
// HelloWorld
//
// Created by feiyin001 on 17/01/04.
// Copyright (c) 2016年 Fable. All rights reserved.
//
#include <iostream>
#include <array>
using namespace std;
const int Size = 5;
template<typename T>
void sum( array < double, Size> a, T& fp);
class Adder
{
double tot;
public:
Adder(double q = 0) : tot(q) {}
void operator()(double w){ tot += w; }
double tot_v() const { return tot; }
};
int main(int argc, char* argv[])
{
double total = 0;
Adder ad(total);
array<double, Size> temp_c = { 32.1, 34.3, 37.8, 35.2, 34.7 };
sum(temp_c, ad);
total = ad.tot_v();
cout << "total: " << ad.tot_v() << endl;
return 0;
}
template<typename T>
void sum(std::array < double, Size> a, T& fp)
{
for (auto pt = a.begin(); pt != a.end(); ++ pt)
{
fp(*pt);
}
}
修改后:
//
// main.cpp
// HelloWorld
//
// Created by feiyin001 on 17/01/04.
// Copyright (c) 2016年 Fable. All rights reserved.
//
#include <iostream>
#include <array>
using namespace std;
const int Size = 5;
template<typename T>
void sum( array < double, Size> a, T& fp);
int main(int argc, char* argv[])
{
double total = 0;
array<double, Size> temp_c = { 32.1, 34.3, 37.8, 35.2, 34.7 };
sum(temp_c, [&total](double w){ total += w; });
cout << "total: " << total << endl;
return 0;
}
template<typename T>
void sum(std::array < double, Size> a, T& fp)
{
for (auto pt = a.begin(); pt != a.end(); ++ pt)
{
fp(*pt);
}
}