C++Primer第五版 第十九章习题答案(21~26)
2017-03-24 09:43
489 查看
21、22、23:知识点1:union是一种特殊的类,可以包含多个数据成员,但是在任意时刻只能有一个数据成员可以有值,其他成员属于未定义的状态,分配给union的内存只要能存储它的最大数据成员即可
知识点2:union中不能含有引用类型的成员,但不可继承、不含有虚函数
知识点3:union的名字就相当于一个类型名,可以使用一对花括号显式初始化:
union Token {};//后面的分号勿忘
Token first_elem = { ' a' };//初始化第一个成员
知识点4:匿名的union,没有名字,其中的成员可以直接访问,匿名union不能包含受保护成员和私有成员,也不能包含成员函数
知识点5:我们通常将含有类类型成员的union内嵌在另一个类之中,将其定义为匿名union,将自身类类型成员的控制权转移给该类
24:赋给自己时,每个成员都会调用自身类所拥有的赋值构造函数,没毛病~
25:见上main.cpp
26:知识点1:类可以定义在函数的内部,称之为局部类,并且必须是完整定义的,其中也不能包含静态成员
知识点2:定义在函数内部的类,不可以使用函数中的局部变量
知识点3:C++从C继承而来的两种不可移植的特性:位域和volatile
知识点4:当一个程序需要向其他程序或者硬件设备传递二进制数据时,通常会用到位域
知识点5:当对象的值可能在程序的控制或检测之外被改变时,应将对象声明为volatile,以此告诉编译器不应对这样的对象进行优化
知识点6:链接指示extern "C",指出任意非C++所用的语言,还可以使extern "Ada"等等,可以加单条语句或复合多条语句,还可以加入头文件
知识点7:C语言不支持重载,因此C链接提示只能说明重载函数中的一个
答案:见知识点7,不合法
知识点2:union中不能含有引用类型的成员,但不可继承、不含有虚函数
知识点3:union的名字就相当于一个类型名,可以使用一对花括号显式初始化:
union Token {};//后面的分号勿忘
Token first_elem = { ' a' };//初始化第一个成员
知识点4:匿名的union,没有名字,其中的成员可以直接访问,匿名union不能包含受保护成员和私有成员,也不能包含成员函数
知识点5:我们通常将含有类类型成员的union内嵌在另一个类之中,将其定义为匿名union,将自身类类型成员的控制权转移给该类
//Token.h #include <iostream> #include <string> #include <utility> #include "Sales_data.h" class Token//19.21 { enum { INT, CHAR, DBL, STR, SALES/*19.22*/ }tok; union { char cval; int ival; double dval; std::string sval; Sales_data sdval;//19.22 }; void copyUnion(const Token &t) { switch (t.tok) { case INT: ival = t.ival; break; case CHAR:cval = t.cval; break; case DBL:dval = t.dval; break; case STR:new(&sval) std::string(t.sval); break; case SALES:new(&sdval) Sales_data(t.sdval);//19.22 break; } } void moveUnion(Token &&t) {//19.23 switch (t.tok) { case INT: ival = std::move(t.ival); break; case CHAR: cval = std::move(t.cval); break; case DBL: dval = std::move(t.dval); break; case STR: new(&sval) std::string(std::move(t.sval)); break; case SALES: new(&sdval) Sales_data(std::move(t.sdval)); break; } } void free() { if (tok == STR) sval.std::string::~string(); if (tok == SALES) sdval.~Sales_data(); } public: Token() :tok(INT), ival{ 0 } {}; Token(const Token &t) :tok(t.tok) { copyUnion(t); } Token(Token &&t) :tok(std::move(t.tok)) {//19.23 moveUnion(std::move(t)); } Token &operator=(Token &&t){//19.23 if(this != &t) { free(); moveUnion(std::move(t)); tok = std::move(t.tok); } return *this; } Token &operator=(const Token &t) { if (tok == STR&&t.tok != STR)sval.std::string::~string(); if (tok == SALES&&t.tok != SALES)sdval.~Sales_data(); if (tok == STR&&t.tok == STR) sval = t.sval; else if (tok == SALES&&t.tok == SALES) sdval = t.sdval; else copyUnion(t); tok = t.tok; return *this; } ~Token() { if (tok == STR) sval.std::string::~string(); if (tok == SALES) sdval.~Sales_data(); } Token &operator=(const std::string &s) { free(); new(&sval) std::string(s); tok = STR; return *this; } Token &operator=(char c) { free(); cval = c; tok = CHAR; return *this; } Token &operator=(int i) { free(); ival = i; tok = INT; return *this; } Token &operator=(double d) { free(); dval = d; tok = DBL; return *this; } Token &operator=(Sales_data &s) { free(); new(&sdval) Sales_data(s); tok = SALES; return *this; } friend std::ostream &operator<<(std::ostream &os, const Token &t) { switch (t.tok) { case Token::INT: os << t.ival; break; case Token::CHAR: os << t.cval; break; case Token::DBL: os << t.dval; break; case Token::STR: os << t.sval; break; case Token::SALES: os << t.sdval; break; } return os; } };
//main.cpp #include <iostream> #include <string> #include "Token.h" int main() { using namespace std; string s = "string"; Sales_data item("c++ primer 5", 12, 128.0); int i = 12; char c = 'c'; double d = 1.28; Token t; t = i; cout << t << "\t"; t = c; cout << t << "\t"; t = d; cout << t << "\t"; t = s; cout << t << "\t"; t = item; cout << t << endl; Token t2 = t; cout << t2 << "\t"; t2 = s; cout << t2 << "\t"; t2 = t; cout << t2 << "\t"; t2 = c; cout << t2 << "\t"; t = s; t2 = std::move(t); cout << t2 << endl; Token t3 = std::move(t2); cout << t3 << "\t"; t3 = t3; cout << t3 << "\t"; t3 = item; cout << t3 << endl; t2 = std::move(t3); cout << t2 << endl; system("pause"); return 0; }
24:赋给自己时,每个成员都会调用自身类所拥有的赋值构造函数,没毛病~
25:见上main.cpp
26:知识点1:类可以定义在函数的内部,称之为局部类,并且必须是完整定义的,其中也不能包含静态成员
知识点2:定义在函数内部的类,不可以使用函数中的局部变量
知识点3:C++从C继承而来的两种不可移植的特性:位域和volatile
知识点4:当一个程序需要向其他程序或者硬件设备传递二进制数据时,通常会用到位域
知识点5:当对象的值可能在程序的控制或检测之外被改变时,应将对象声明为volatile,以此告诉编译器不应对这样的对象进行优化
知识点6:链接指示extern "C",指出任意非C++所用的语言,还可以使extern "Ada"等等,可以加单条语句或复合多条语句,还可以加入头文件
知识点7:C语言不支持重载,因此C链接提示只能说明重载函数中的一个
答案:见知识点7,不合法
相关文章推荐
- C++Primer第五版 第六章习题答案(21~30)
- C++Primer第五版 第三章习题答案(21~30)
- C++Primer第五版 第七章习题答案(21~30)
- C++Primer第五版 第九章习题答案(21~30)
- C++Primer第五版 第十九章习题答案(1~10)
- C++Primer第五版 第十六章习题答案(21~30)
- C++Primer第五版 第十九章习题答案(11~20)
- C++Primer第五版 第五章习题答案(21~25)
- C++Primer第五版 第十章习题答案(21~30)
- C++Primer第五版 第十一章习题答案(21~30)
- C++Primer第五版 第十三章习题答案(21~30)
- C++Primer第五版 第二章习题答案(21~30)
- C++Primer第五版 第十二章习题答案(21~30)
- C++Primer第五版 第十五章习题答案(21~30)
- C++Primer第五版 第十八章习题答案(21~30)
- C++Primer第五版 第四章习题答案(21~30)
- C++Primer第五版 第二章习题答案(1~10)
- C++Primer第五版 第九章习题答案(51~52)
- C++Primer 中文版 第五版 第二章课后习题答案
- C++Primer第五版 第十七章习题答案