19.1:
#include<cstdlib>
#include<iostream>
using namespace std;
void* operator new(size_t size)
{
if (void* mem = malloc(size))
{
return mem;
}
else
{
throw bad_alloc();
}
}
void operator delete(void* mem)noexcept
{
free(mem);
}
9.3:
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <typeinfo>
using namespace std;
class A
{
public:
A()
{
cout << "A()" << endl;
}
virtual ~A()
{
cout << "~A()" << endl;
}
};
class B :public A
{
public:
B()
{
cout << "B()" << endl;
}
virtual ~B()
{
cout << "~B()" << endl;
}
};
class C :public B
{
public:
C()
{
cout << "C()" << endl;
}
virtual ~C()
{
cout << "~C()" << endl;
}
};
class D :public B, public A
{
public:
D()
{
cout << "D()" << endl;
}
virtual ~D()
{
cout << "~D()" << endl;
}
};
int main(int argc, char** argv)
{
A* pa = new C;
if (B* pb = dynamic_cast<B*>(pa))
{
cout << "True" << endl;
}
else
{
cout << "False" << endl;
}//因为指针类型的转换失败返回为0可以使用条件中赋值判断
try
{
C& cp = dynamic_cast<C&>(*pa);//正确,*pa的类型是C
cout << "cp" << endl;
}
catch (std::bad_cast e)
{
cout << e.what() << endl;
}//引用类型失败返回的是bad_cast
B* pbb = new B;
if (C* pc = dynamic_cast<C*>(pbb))
{
cout << "True" << endl;
}
else
{
cout << "False" << endl;
}
A* paa = new D;
if (B* pc = dynamic_cast<C*>(paa))
{
cout << "True" << endl;
}
else
{
cout << "False" << endl;
}
cin.get();
return 0;
}
19.6:
#include<iostream>
using namespace std;
class Base{
virtual void print()
{}
};
class Derived:public Base{};
int main()
{
Derived* dp = new Derived;
Base* bp = dp;
bool b = (typeid(*dp)== typeid(*bp));
cout << b << endl;
}
19.9:
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <typeinfo>
using namespace std;
int main(int argc, char** argv)
{
int arr[41];
double i = 6.23;
vector<int> vec1;
int* p = arr;
cout << typeid(arr).name() << endl;
cout << typeid(i).name() << endl;
cout << typeid(vec1).name() << endl;
cout << typeid(p).name() << endl;
cin.get();
return 0;
}
19.12:
#include <string>
#include <iostream>
class Screen {
public:
using pos = std::string::size_type;
static const std::string Screen::* data() { return &Screen::contents; }
static const pos Screen::* pcursor() { return &Screen::cursor; }
Screen() = default;
Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht* wd, c) { }
char get() const { return contents[cursor]; }
char get(pos r, pos c) const { return contents[r * width + c]; }
private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
};
int main()
{
// const std::string Screen::*pdata;
// pdata = &Screen::contents;
// auto pdata = &Screen::contents; //contents is private
const std::string Screen::* pdata = Screen::data();
Screen myScreen(2, 2, 'c');
auto s = myScreen.*pdata;
std::cout << s << std::endl;
const std::string::size_type Screen::* pcursor = Screen::pcursor();
auto i = myScreen.*pcursor;
std::cout << i << std::endl;
return 0;
}
19.17:
#include <string>
#include <iostream>
using namespace std;
class Screen {
public:
using pos = string::size_type;
static const string Screen::* data() { return &Screen::contents; }
static const pos Screen::* pcursor() { return &Screen::cursor; }
Screen() = default;
Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht* wd, c) { }
char get() const { return contents[cursor]; }
char get(pos r, pos c) const { return contents[r * width + c]; }
private:
pos cursor = 0;
pos height = 0, width = 0;
string contents;
};
int main()
{
Screen myScreen(2, 2, 'c');
using getptr1 = char(Screen::*)()const;
getptr1 getp = &Screen::get;
using getptr2 = char(Screen::*)(Screen::pos, Screen::pos)const;
getptr2 getp2 = &Screen::get;
cout << (myScreen.*getp)() << endl;
Screen* p = &myScreen;
cout << (p->*getp2)(0, 0) << endl;
return 0;
}
19.18:
#include <string>
#include <iostream>
using namespace std;
#include<vector>
#include<functional>
#include<algorithm>
using placeholders::_1;
int main()
{
vector<string>ves;
ves.push_back("1123");
ves.push_back("");
ves.push_back("asd");
auto it = count_if(ves.begin(), ves.end(), mem_fn(&string::empty));
cout << it << endl;
auto it2 = count_if(ves.begin(), ves.end(), bind(&string::empty,_1));
cout << it2 << endl;
function<bool(const string&)> fcn = &string::empty;
auto it3 = count_if(ves.begin(), ves.end(), fcn);
cout << it3 << endl;
return 0;
}
19.19:
#include <string>
#include <iostream>
using namespace std;
#include<vector>
#include"Sales_data.h"
#include<functional>
using placeholders::_1;
vector<Sales_data>::const_iterator search(const vector<Sales_data>& s, double p)
{
auto fun = bind(&Sales_data::avg_price, _1);
return find_if(s.begin(), s.end(), [&](const Sales_data& sa) {return p < fun(sa); });
}
int main()
{
std::vector<Sales_data> v;
Sales_data a("123", 2, 3);
v.push_back(a);
v.push_back(Sales_data("234", 3, 5));
std::cout << *search(v, 4) << std::endl;
return 0;
}
19.21:
#include<iostream>
using namespace std;
#include<string>
class Token
{
friend ostream& operator <<(ostream& os, const Token& t);
public:
Token():tok(INT),ival{0} {}
Token(const Token& t) :tok(t.tok) { copyUnion(t); }
Token& operator=(const Token&);
~Token() { if (tok == STR)sval.~string(); }
Token& operator=(const string&);
Token& operator=(char);
Token& operator=(int);
Token& operator=(double);
private:
enum { INT, CHAR, DBL, STR }tok;
union
{
char cval;
int ival;
double dval;
string sval;
};
void copyUnion(const Token&);
};
Token& Token::operator=(int i)
{
if (tok == STR)sval.~string();
ival = i;
tok = INT;
return *this;
}
Token& Token::operator=(const string& s)
{
if (tok == STR)
{
sval = s;
}
else
{
new(&sval) string(s);
}
tok = STR;
return *this;
}
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;
}
}
Token& Token::operator=(const Token& t)
{
if (tok == STR && t.tok != STR)
{
sval.~string();
}
if (tok == STR && t.tok == STR)
{
sval = t.sval;
}
else
{
copyUnion(t);
}
tok = t.tok;
return *this;
}
Token& Token::operator=(char c)
{
if (tok == STR)sval.~string();
cval = c;
tok = CHAR;
return *this;
}
Token& Token::operator=(double d)
{
if (tok == STR)sval.~string();
dval = d;
tok = DBL;
return *this;
}
ostream& operator <<(ostream& os, const Token& t)
{
switch (t.tok)
{
case Token::INT:
cout << "INT " << t.ival;
break;
case Token::CHAR:
cout << "CHAR " << t.cval;
break;
case Token::DBL:
cout << "DBL " << t.dval;
break;
case Token::STR:
cout << "STR " << t.sval;
break;
}
return os;
}
int main()
{
Token t, t1;
std::cout << t << std::endl;
t = 3;
std::cout << t << std::endl;
t = 'q';
std::cout << t << std::endl;
t = 3.14;
std::cout << t << std::endl;
t = std::string("qwerty");
std::cout << t << std::endl;
t = std::string("qaz");
std::cout << t << std::endl;
t = t;
std::cout << t << std::endl;
t1 = 'q';
t = t1;
std::cout << t << std::endl;
return 0;
}
19.22:
#include<iostream>
using namespace std;
#include<string>
#include"Sales_data.h"
class Token
{
friend ostream& operator <<(ostream& os, const Token& t);
public:
Token():tok(INT),ival{0} {}
Token(const Token& t) :tok(t.tok) { copyUnion(t); }
Token& operator=(const Token&);
~Token();
Token& operator=(const string&);
Token& operator=(char);
Token& operator =(const Sales_data&);
Token& operator=(int);
Token& operator=(double);
private:
enum { INT, CHAR, DBL, STR,SALE }tok;
union
{
char cval;
int ival;
double dval;
string sval;
Sales_data saval;
};
void copyUnion(const Token&);
};
Token::~Token()
{
if (tok == STR)
sval.~basic_string();
if (tok == SALE)
saval.~Sales_data();
}
Token& Token::operator=(int i)
{
if (tok == STR)sval.~basic_string();
if (tok == SALE)saval.~Sales_data();
ival = i;
tok = INT;
return *this;
}
Token& Token::operator=(const string& s)
{
if (tok == SALE)saval.~Sales_data();
if (tok == STR)
{
sval = s;
}
else
{
new(&sval) string(s);
}
tok = STR;
return *this;
}
Token& Token::operator =(const Sales_data& s)
{
if (tok == STR)sval.~basic_string();
if (tok == SALE)saval = s;
else
{
new(&saval) Sales_data(s);
}
tok = SALE;
return *this;
}
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::SALE: new(&saval) Sales_data(t.saval); break;
}
}
Token& Token::operator=(const Token& t)
{
if (tok == STR && t.tok != STR)
{
sval.~basic_string();
}
if (tok == SALE && t.tok != SALE)
{
saval.~Sales_data();
}
if (tok == STR && t.tok == STR)
{
sval = t.sval;
}
else if (tok == SALE && t.tok == SALE)
{
saval = t.saval;
}
else
{
copyUnion(t);
}
tok = t.tok;
return *this;
}
Token& Token::operator=(char c)
{
if (tok == SALE)saval.~Sales_data();
if (tok == STR)sval.~basic_string();
cval = c;
tok = CHAR;
return *this;
}
Token& Token::operator=(double d)
{
if (tok == STR)sval.~basic_string();
if (tok == SALE)saval.~Sales_data();
dval = d;
tok = DBL;
return *this;
}
ostream& operator <<(ostream& os, const Token& t)
{
switch (t.tok)
{
case Token::INT:
cout << "INT " << t.ival;
break;
case Token::CHAR:
cout << "CHAR " << t.cval;
break;
case Token::DBL:
cout << "DBL " << t.dval;
break;
case Token::STR:
cout << "STR " << t.sval;
break;
case Token::SALE:
cout << "SALE " << t.saval;
break;
}
return os;
}
int main()
{
Sales_data a(std::string("qweasd"), 1, 2.0);
Token t, t1;
std::cout << t << std::endl;
t = 3;
std::cout << t << std::endl;
t = 'q';
std::cout << t << std::endl;
t = 3.14;
std::cout << t << std::endl;
t = std::string("qwerty");
std::cout << t << std::endl;
t = std::string("qaz");
std::cout << t << std::endl;
t = a;
std::cout << t << std::endl;
t = t;
std::cout << t << std::endl;
t1 = 'q';
t = t1;
std::cout << t << std::endl;
return 0;
}
19.23:
#include<iostream>
using namespace std;
#include<string>
#include"Sales_data.h"
class Token
{
friend ostream& operator <<(ostream& os, const Token& t);
public:
Token():tok(INT),ival{0} {}
Token(const Token& t) :tok(t.tok) { copyUnion(t); }
Token& operator=(const Token&);
~Token();
Token& operator=(const string&);
Token& operator=(char);
Token& operator =(const Sales_data&);
Token& operator=(int);
Token& operator=(double);
Token(Token&&) noexcept;
Token& operator=(Token&&)noexcept;
private:
enum { INT, CHAR, DBL, STR,SALE }tok;
union
{
char cval;
int ival;
double dval;
string sval;
Sales_data saval;
};
void copyUnion(const Token&);
void moveUnion(Token&&);
};
Token::~Token()
{
if (tok == STR)
sval.~basic_string();
if (tok == SALE)
saval.~Sales_data();
}
Token& Token::operator=(int i)
{
if (tok == STR)sval.~basic_string();
if (tok == SALE)saval.~Sales_data();
ival = i;
tok = INT;
return *this;
}
Token& Token::operator=(const string& s)
{
if (tok == SALE)saval.~Sales_data();
if (tok == STR)
{
sval = s;
}
else
{
new(&sval) string(s);
}
tok = STR;
return *this;
}
Token& Token::operator =(const Sales_data& s)
{
if (tok == STR)sval.~basic_string();
if (tok == SALE)saval = s;
else
{
new(&saval) Sales_data(s);
}
tok = SALE;
return *this;
}
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::SALE: new(&saval) Sales_data(t.saval); break;
}
}
Token& Token::operator=(const Token& t)
{
if (tok == STR && t.tok != STR)
{
sval.~basic_string();
}
if (tok == SALE && t.tok != SALE)
{
saval.~Sales_data();
}
if (tok == STR && t.tok == STR)
{
sval = t.sval;
}
else if (tok == SALE && t.tok == SALE)
{
saval = t.saval;
}
else
{
copyUnion(t);
}
tok = t.tok;
return *this;
}
Token& Token::operator=(char c)
{
if (tok == SALE)saval.~Sales_data();
if (tok == STR)sval.~basic_string();
cval = c;
tok = CHAR;
return *this;
}
Token& Token::operator=(double d)
{
if (tok == STR)sval.~basic_string();
if (tok == SALE)saval.~Sales_data();
dval = d;
tok = DBL;
return *this;
}
ostream& operator <<(ostream& os, const Token& t)
{
switch (t.tok)
{
case Token::INT:
cout << "INT " << t.ival;
break;
case Token::CHAR:
cout << "CHAR " << t.cval;
break;
case Token::DBL:
cout << "DBL " << t.dval;
break;
case Token::STR:
cout << "STR " << t.sval;
break;
case Token::SALE:
cout << "SALE " << t.saval;
break;
}
return os;
}
void Token::moveUnion(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(std::move(t.sval));
break;
case Token::SALE:
new(&saval) Sales_data(std::move(t.saval));
break;
}
}
Token::Token(Token&& t)noexcept :tok(t.tok)
{
moveUnion(std::move(t));
}
Token& Token::operator=(Token&& t) noexcept
{
if (&t == this)
return *this;
if (tok == STR && t.tok != STR)
sval.~basic_string();
if (tok == SALE && t.tok != SALE)
saval.~Sales_data();
if (tok == STR && t.tok == STR)
sval = std::move(t.sval);
else if (tok == SALE && t.tok == SALE)
saval = std::move(t.saval);
else
moveUnion(std::move(t));
return *this;
}
int main()
{
Sales_data a(std::string("qweasd"), 1, 2.0), b(std::string("qweasd"), 2, 3.0);
Token t, t1;
std::cout << t << std::endl;
t = 3;
std::cout << t << std::endl;
t = 'q';
std::cout << t << std::endl;
t = 3.14;
std::cout << t << std::endl;
t = std::string("qwerty");
std::cout << t << std::endl;
t = std::string("qaz");
std::cout << t << std::endl;
t = a;
std::cout << t << std::endl;
t = std::move(t);
std::cout << t << std::endl;
t1 = b;
t = std::move(t1);
std::cout << t << std::endl;
std::cout << t1 << std::endl;
return 0;
}