博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第十九章 特殊工具与技术
阅读量:5815 次
发布时间:2019-06-18

本文共 5818 字,大约阅读时间需要 19 分钟。

19.1

#include 
#include
using namespace std;void* operator new(size_t n){ if (void *p = malloc(n)) return p; else throw bad_alloc();} void operator delete(void *p) noexcept{ free(p);}int main(){ int *ps = new int; delete ps; return 0;}

  

19.2

allocator类将使用我们自定义的版本替换标准库定义的版本,来获取/释放存储空间。

 

19.3

(a):失败,pa指向派生类C,而B是C的基类,故无法转换

(b):成功

(c):失败,同(a)

其他人的答案:

(a):正确,pa指向C构造的对象的A部分

(b):失败,pb指向的对象不包含C对象

(c):正确

 

19.4

A *pa = new C;		//pa指向C,*pa的类型是C 	try {		C &c = dynamic_cast
(*pa); //使用C的成员 } catch(bad_cast) { //使用A的成员 }

  

19.5

使用dynamic_cast运算符代替虚函数:使用基类对象的指针或引用执行某个(不是虚函数)派生类操作时

 

19.6

Query_base *q = new AndQuery(Query("val1"), Query("val2"));	AndQuery a(Query("ss1"), Query("ss2"));	if (typeid(*q) == typeid(a))		cout << "success\n";	else		cout << "failure\n";

  

19.7

Query_base q;	AndQuery a(Query("ss1"), Query("ss2"));	try {		AndQuery aa = dynamic_cast
(q); cout << "success\n"; } catch (bad_cast) { cout << "failure\n"; }

  

19.8

Query_base *pb1 = new AndQuery(Query("value1"), Query("value2"));      Query_base *pb2 = new OrQuery(Query("value1"), Query("value2"));     if (typeid(*pb1) == typeid(*pb2))          cout << "pb1与pb2指向的对象类型相同" << endl;      else          cout << "pb1与pb2的动态类型不相同" << endl;      if (typeid(*pb1) == typeid(AndQuery))          cout << "pb1的动态类型是AndQuery" << endl;      else          cout << "pb1的动态类型并非是AndQuery" << endl;      if (typeid(*pb2) == typeid(AndQuery))          cout << "pb2的动态类型是AndQuery" << endl;      else          cout << "pb2的动态类型并非是AndQuery" << endl;

  

19.9

#include 
#include
using namespace std;int main(){ int i = 2, a[10] = {0}; double d = 0; string s; cout << typeid(i).name() << endl << typeid(a).name() << endl << typeid(d).name() << endl << typeid(s).name() << endl; return 0;}

  

19.10

(a):类型A*

(b):类型C*

(c):类型B

 

19.11

普通的数据指针:指向一个对象

指向数据成员的指针:指示的是类的成员(而非类的对象)

 

19.12

#include 
#include
using namespace std;class Screen {public: typedef string::size_type pos; Screen(): cursor(0), height(0), width(0) {} char get_cursor() const { return contents[cursor]; } char get() const; char get(pos ht, pos wd) const; static pos Screen::* co() { return &Screen::cursor; }// pos Screen::*p = &Screen::cursor;private: string contents; pos cursor; pos height, width;};int main(){ Screen scr; auto p = scr.co(); auto ans = scr.*p; cout << ans << endl; return 0;}

  

19.13

类型:const string Sales_data::*

示例:const string Sales_data::*p = &Sales_data::bookNo;

 

19.14

第一个合法:pmf为指向Screen类成员函数get_cursor的指针

第二个不合法:get函数存在重载的问题,我们必须显式地声明函数类型以明确指出我们想要使用的是哪个函数

修正:

char (Screen::*pmf)(Screen::pos, Screen::pos) const;	pmf = &Screen::get;	//way2	using Action = char (Screen::*)(Screen::pos, Screen::pos) const;	Action pmf = &Screen::get;

  

19.15

指向成员函数的指针:在成员函数和指向该成员的指针之间不存在自动转换规则

 

19.16

using Action = double (Sales_data::*)() const;

  

19.17

char get() const { return contents[cursor]; }//using Action_c_v = char (Screen::*)()const;  char get_cursor() const { return contents[cursor]; }//同上  inline char get(pos ht, pos wd) const;//using Action_c_uu = char (Screen::*)(pos,pos)const;  Screen &move(pos r, pos c);//using Action_Screen_uu = Screen &(Screen::*)(pos,pos);

  

19.18

int a = count_if(svec.begin(), svec.end(), bind(&string::empty, _1));

  

19.21

#include 
using namespace std;class Token {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&);}; void Token::copyUnion(const Token &t){ switch (t.tok) { case INT: ival = t.ival; break; case CHAR: cval = t.cval; break; case DBL: dval = t.dval; case STR: new(&sval) string(t.sval); break; }}Token &Token::operator=(const Token &t){ if (tok == STR && t.tok != STR) sval.~string(); else if (tok == STR && t.tok == STR) sval = t.sval; else copyUnion(t); tok = t.tok; return *this;}Token &Token::operator=(int i){ if (tok == STR) sval.~string(); ival = i; tok = INT; return *this;}Token &Token::operator=(double d){ if (tok == STR) sval.~string(); dval = d; tok = DBL; return *this;}Token &Token::operator=(char c){ if (tok == STR) sval.~string(); cval = c; tok = CHAR; return *this;}Token &Token::operator=(const string &s){ if (tok == STR) sval = s; else new(&sval) string(s); tok = STR; return *this;}

  

19.22

class Token {public:	//其他见上题 	class Sales_data;};

  

19.23

Token(Token &&t): tok(std::move(t.tok)) { moveUnion(std::move(t)); }	Token &operator=(Token &&t);

  

19.24

将一个Token对象赋给另一个Token对象:会运行拷贝赋值运算符,然后根据判别式的值来对相应的数据成员赋值。

类似的,将一个Token对象赋给它自己的过程和上面的类似。

 

19.25

Token &Token::operator=(int i){	if (tok == STR)		sval.~string();	ival = i;	tok = INT;	return *this;}Token &Token::operator=(double d){	if (tok == STR)		sval.~string();	dval = d;	tok = DBL;	return *this;}Token &Token::operator=(char c){	if (tok == STR)		sval.~string();	cval = c;	tok = CHAR;	return *this;}Token &Token::operator=(const string &s){	if (tok == STR)		sval = s;	else		new(&sval) string(s);	tok = STR;	return *this;}

补充:

Token &Token::operator=(const Token &t){	if (tok == STR && t.tok != STR)		sval.~string();	else if (tok == STR && t.tok == STR)		sval = t.sval;	else		copyUnion(t);		//内含各种类型的赋值 	tok = t.tok;	return *this;}void Token::copyUnion(const Token &t){	switch (t.tok) {		case INT: 			ival = t.ival;			break;		case CHAR:			cval = t.cval;			break;		case DBL:			dval = t.dval;		case STR:			new(&sval) string(t.sval);			break;	}}

  

19.26

错误,C语言不支持函数重载

 

转载于:https://www.cnblogs.com/xzxl/p/7806162.html

你可能感兴趣的文章
mui 总结2--新建第一个app项目
查看>>
nginx的lua api
查看>>
考研太苦逼没坚持下来!看苑老师视频有点上头
查看>>
HCNA——RIP的路由汇总
查看>>
zabbix监控php状态(四)
查看>>
定时任务的创建
查看>>
实战Django:小型CMS Part2
查看>>
原创]windows server 2012 AD架构试验系列 – 16更改DC计算机名
查看>>
统治世界的十大算法
查看>>
linux svn安装和配置
查看>>
SSH中调用另一action的方法(chain,redirect)
查看>>
数据库基础
查看>>
表格排序
查看>>
关于Android四大组件的学习总结
查看>>
java只能的round,ceil,floor方法的使用
查看>>
由于无法创建应用程序域,因此未能执行请求。错误: 0x80070002 系统找不到指定的文件...
查看>>
新开的博客,为自己祝贺一下
查看>>
puppet任务计划
查看>>
【CQOI2011】放棋子
查看>>
采用JXL包进行EXCEL数据写入操作
查看>>