第十九章 19.2.4节练习

练习19.9

编写与本节最后一个程序类似的代码,令其打印你的编译器为一些常见类型所起的名字。

如果你得到的输出与本书类似,尝试编写一个函数将这些字符串翻译成人们更容易理解的形式。

解答:

<pre name="code" class="cpp">#include <iostream>
#include <typeinfo>
#include <vector>
#include <list>
#include <string>
#include <map>
#include <regex>

using namespace std;

string type_map(const string& str){
  string res_str;
  if(str.size() == 1){
    switch(str.at(0)){
      case 'c': res_str = "char"; break;
      case 'h': res_str = "unsigned char"; break;
      case 's': res_str = "short"; break;
      case 't': res_str = "unsigned short"; break;
      case 'i': res_str = "int"; break;
      case 'j': res_str = "unsigned int"; break;
      case 'l': res_str = "long"; break;
      case 'f': res_str = "float"; break;
      case 'd': res_str = "double"; break;
      case 'm': res_str = "size_t"; break;
      case 'x': res_str = "long long"; break;
      case 'y': res_str = "unsigned long long"; break;
      case 'e': res_str = "long double"; break;
    }
  } else {
    return string();
  }
  return res_str;
}

void parse(const char* cstr){
  size_t ch_num;
  string str(cstr), res_str, patten("");
  smatch res, res_2;

  regex r1("([APSt]*)?([0-9]*)?([_]*)?([P]*)?([0-9]*)?([A-Za-z0-9_]*)?");

  regex_search(str, res, r1);

  if (!res[2].str().empty()){
    ch_num = atoi(res[2].str().c_str());
    patten = "([A-Za-z0-9_]{" + res[2].str() + "})(I)?([a-z])?";
  }

  regex r2(patten);

  if (res.str().size() == 1){
    res_str += type_map(res.str());
  } else if (res[1].str() == "A" && ch_num != 0){
    if(res[4].str() == "P"){
      res_str += "*";
    } else if(res[4].str() == "PP"){
      res_str += "**";
    }
    if (res[6].str().size() == 1){
      res_str += type_map(res[6].str());
    } else {
      res_str += res[6].str();
    }
    res_str += "[" + res[2].str()  + "]";
  } else if (res[1].str() == "P"){
    res_str += "*";
    if (res[6].str().size() == 1){
      res_str += type_map(res[6].str());
    } else {
      regex_search(res[6].str(), res_2, r2);
      res_str += res_2.str();
    }
  } else if (res[1].str() == "PP"){
    res_str += "**";
    regex_search(res[6].str(), res_2, r2);
    if (res[6].str().size() == 1){
      res_str += type_map(res[6].str());
    } else {
      regex_search(res[6].str(), res_2, r2);
      res_str += res_2.str();
    }
  } else if (res[1].str() == "S"){
    res_str += "std::";
    if (res[6].str() == "s"){
      res_str += "string";
    }
  } else if (res[1].str() == "St"){
    res_str += "STL ";
    regex_search(res[6].str(), res_2, r2);
    res_str += res_2[1].str();
    res_str += "<";
    res_str += type_map(res_2[3].str());
    res_str += ">";
  } else{
    regex_search(res[6].str(), res_2, r2);
    res_str += res_2.str();
  }
  // TODO map type

  cout << "this object type is " << res_str << "." << endl;
}

#ifdef WIN32
#define parse(a) cout << (a) << endl
#endif

class Base{};

int main(){
  int inum;
  int *pa;
  int **ppa;
  long long larr[10];
  Base *pb;
  Base **ppb;
  Base barr[100];
  Base base;
  vector<float> iv;
  list<float> fl;

  parse(typeid(inum).name());
  parse(typeid(pa).name());
  parse(typeid(ppa).name());
  parse(typeid(larr).name());
  parse(typeid(pb).name());
  parse(typeid(ppb).name());
  parse(typeid(barr).name());
  parse(typeid(base).name());
  parse(typeid(iv).name());
  parse(typeid(fl).name());
}


 我这里实现的也不简单…… 自己都感觉很复杂,各种判断…… 

本来以为可以一个函数搞定的,写到后面才发现这个分析也不是很简单。

本来还要加pair和map的,看了一下输出字符…… 放弃了。

如果觉得有必要,可以用自定义类进行分析。(做过视频处理程序的朋友可能能理解为什么这样做)


在linux下,clang和gcc的输出和书上的一致。(我当前工作的环境也是linux)

当然,也在VS2013中试过,VS更加的友好,显示出来的类能直接进行判别。

相同代码,使用cout将typeid().name()打印出来的结果:(代码也做了相应的修改)

int
int *
int * *
__int64 [10]
class Base *
class Base * *
class Base [100]
class Base
class std::vector<float,class std::allocator<float> >
class std::list<float,class std::allocator<float> >

练习19.10

已知存在如下的类继承体系,其中每个类定义了一个默认公有的构造函数和一个虚析构函数。下面的语句将打印哪些类型名字?

class A{/* ... */};

class B : public A {/*...*/

class C : public B {/*...*/};

(a) A *pa = new C;

      cout << typeid(pa).name() << endl;

(b) C cobj;

      A& ra = cobj;

      cout << typeid(&ra).name() << endl;

(c) B *px = new B;

      A& ra = *px;

      cout << typeid(ra).name() << endl;

解答:

(a) P1A

(b) P1A

(c) 1B (注意这里是对指针的引用)

#include <iostream>
#include <typeinfo>

using namespace std;

class A{
public:
  A() = default;
  virtual ~A(){}
};

class B : public A {
public:
  B() = default;
  virtual ~B(){};
};

class C : public B {
public:
  C() = default;
  virtual ~C(){};
};

#define choose 2

int main(){
#if choose == 1
  A *pa = new C;
  cout << typeid(pa).name() << endl;
#elif choose == 2
  C cobj;
  A& ra = cobj;
  cout << typeid(&ra).name() << endl;
#else
  B *px = new B;
  A& ra = *px;
  cout << typeid(ra).name() << endl;
#endif
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值