c++ primer 第十九章習題
阿新 • • 發佈:2018-11-11
c++ primer 第十九章習題
練習19.1 2
#include <iostream> #include <cstdlib> void *operator new(std::size_t n){ std::cout << "my new"<<endl; if (void *mem = malloc(n)) return mem; else throw std::bad_alloc(); } void operator delete(void *mem) noexcept{ std::cout << "my delete"<<endl; free(mem); } int main() { using namespace std; int *a = new int(486); cout << a << " " << *a << endl; delete a; return 0; }
練習19.3 (a T (b F 因為pb實際指向的物件是C的基類無法轉換 (c T
練習19.4
try {
C& pc = dynamic_cast<C&>(*pa);
//
}
catch(bad_cast) {
}
練習19.5 當不能夠使用虛擬函式完成又需要用基類指標或引用呼叫派生類成員的時候。
練習19.10 (a A* (b A& (c B&
練習19.11 區別在於指向資料成員的指標沒有指定物件,呼叫符號不同,需要考慮訪問許可權。
練習19.12 const Screen::pos Screen::*pdata = &Screen::cursor;
練習19.13 const std::string Sales_data::*pdata = &Sales_data::bookNo;
練習19.14 合法
練習19.15 呼叫的符號,需要考慮類內許可權,函式與指標不會自動轉換。
練習19.16 using avg = (double)(Sales_data::*)() const;
練習19.18 count_if(vec.begin(),vec.end(),mem_fn(&string::empty));
練習19.19
vector<Sales_data>::iterator largerThanD(vector<Sales_data>& vec, double d) { double d = 0; auto fn = mem_fn(&Sales_data::avg); return find_if(vec.begin(),vec.end(),[&](string&s){return fn(s) > d;} }
練習19.21-25
#ifndef TOKEN_H
#define TOKEN_H
#include<iostream>
#include<string>
#include "Sales_data.h"
using std::string;
class Token
{
friend std::ostream &operator<<(std::ostream &os, const Token &t);
public:
Token():tok(INT),ival(0){}
Token(const Token& t):tok(t.tok){copyUnion(t);}
Token(Token&& t):tok(std::move(t.tok)){copyUnion(std::move(t));}
Token& operator=(Token&& t);
Token& operator=(const Token& t);
~Token(){if(tok == STR) sval.~string();}
Token& operator=(const string&);
Token& operator=(const Sales_data&);
Token& operator=(char);
Token& operator=(int);
Token& operator=(double);
private:
union {
char cval;
int ival;
double dval;
string sval;
Sales_data sdval;
};
enum {INT, CHAR, DBL, STR,SDA} tok;
void copyUnion(const Token& );
void copyUnion(Token&&);
};
inline void Token::copyUnion(const Token& t) {
switch(t.tok) {
case Token::INT: ival = t.ival;break;
case Token::CHAR: cval = t.cval;break;
case Token::DBL: dval = t.dval;break;
case Token::STR: new(&sval) string(t.sval);break;
case Token::SDA: new(&sdval) Sales_data(t.sdval); break;
}
}
inline void Token::copyUnion(Token&& t) {
switch(t.tok) {
case Token::INT: ival = std::move(t.ival);break;
case Token::CHAR: cval = std::move(t.cval);break;
case Token::DBL: dval = std::move(t.dval);break;
case Token::STR: new(&sval) string(std::move(t.sval));break;
case Token::SDA: new(&sdval) Sales_data(std::move(t.sdval)); break;
}
}
Token& Token::operator=(Token&& t){
if(tok == STR)
if (t.tok == STR){
sval = std::move(t.sval);
return *this;
}
else
sval.~string();
if(tok == SDA)
if(t.tok == SDA){
sdval = std::move(t.sdval);
return *this;
}
else
sdval.~Sales_data();
tok = std::move(t.tok);
copyUnion(std::move(t));
return *this;
}
Token& Token::operator=(const Token& t){
if(tok == STR)
if (t.tok == STR){
sval = t.sval;
return *this;
}
else
sval.~string();
if(tok == SDA)
if(t.tok == SDA){
sdval = t.sdval;
return *this;
}
else
sdval.~Sales_data();
tok = t.tok;
copyUnion(t);
return *this;
}
Token& Token::operator=(const string& s){
if( tok == STR) {
sval = s;
}else {
if(tok == SDA)
sdval.~Sales_data();
new(&sval) string(s);
tok = STR;
}
return *this;
}
Token& Token::operator=(const Sales_data& sa){
if( tok == SDA) {
sdval = sa;
}else {
if(tok == STR)
sval.~string();
new(&sdval) Sales_data(sa);
tok = SDA;
}
return *this;
}
Token& Token::operator=(char c) {
if(tok == STR) sval.~string();
if(tok == SDA) sdval.~Sales_data();
cval = c;
tok = CHAR;
return *this;
}
Token& Token::operator=(int i) {
if (tok == STR) sval.~string();
if(tok == SDA) sdval.~Sales_data();
ival = i;
tok = INT;
return *this;
}
Token& Token::operator=(double d) {
if (tok == STR) sval.~string();
if(tok == SDA) sdval.~Sales_data();
dval = d;
tok = DBL;
return *this;
}
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::SDA: os << t.sdval; break;
}
return os;
}