1:神奇的MyAny
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
编写 MyAny类以及,MyAny_cast模版(可能多个),使得程序按要求输出
要求MyAny类必须要有析构函数,在析构函数以及其他适当的地方(比如复制构造函数,重载的赋值号)要释放动态分配的空间,不能造成内存碎片。
-
#include <iostream> #include <vector> #include <string> #include <typeinfo> using namespace std; class MyClass { public: int n; MyClass(int m):n(m) { } void f() { cout << n << " func." << endl; } };
// 在此处补充你的代码
int main() { while(true) { int n; string s; cin >> n >> s; if ( n == 0) break; MyAny a = n; cout << MyAny_cast<int>(a) << endl; a = s; cout << MyAny_cast<string>(a) << endl; a = MyClass(n+1); MyAny b = n + 2; MyAny * p = new MyAny(MyClass(n+3)); MyAny c = MyClass(n+4); c = * p; b = * p; delete p; MyAny d = b; MyAny_cast<MyClass>(&a)->f(); MyAny_cast<MyClass>(&b)->f(); MyAny_cast<MyClass>(&c)->f(); MyAny_cast<MyClass>(&d)->f(); c = s + "OK"; cout << MyAny_cast<string>(c) << endl; int * pi = MyAny_cast<int> ( & c); if( pi == NULL) cout << "not a int" << endl; else cout << "the int is " << * pi << endl; string * ps = MyAny_cast<string> ( & c); if( ps == NULL) cout << "not a string" << endl; else cout << "the string is " << * ps << endl; } }输入多组数据,每组一行,为一个整数n和一个无空格字符串s。输出对每组数据,输出以下内容
n
s
n+1 func.
n+3 func.
n+3 func.
n+3 func.
sOK
not a int
the string is sOK
n,n+1,n+3都用具体的数值替换
s用读入的字符串替代样例输入
5 good 6 hello 0 0样例输出
5 good 6 func. 8 func. 8 func. 8 func. goodOK not a int the string is goodOK 6 hello 7 func. 9 func. 9 func. 9 func. helloOK not a int the string is helloOK提示1. 可以参考 boost的 any的代码
2. MyAny_cast 模板可以写两个
3. 可以为MyAny类 写一个 模板的 operator =
4. 使用 type_info,typeid进行类型方面的判断。注意type_info 的复制构造函数是私有的,
5. typeid(x)返回一个 type_info对象的引用,里面描述了 x的类型信息。
可以用 typeid(a) == typeid(b)判断a 和b的类型是否一致
这道题是自己写一个类似boost中any的函数,这种动态类型是c++不支持,但很多其他的语言都支持的一种用法。很有意思的一道题。思路是用内部类的继承和多态来实现,MyAny类中只有一个指向base类的指针,这个指针可以指向各种不同的derive类,derive类是一个模板类,随参数动态的变化,每次要使用有特征的函数就利用多态机制去实现即可。代码如下:
#include <iostream> #include <vector> #include <string> #include <typeinfo> using namespace std; class MyClass { public: int n; MyClass(int m):n(m) { } void f() { cout << n << " func." << endl; } }; // 在此处补充你的代码 class MyAny { public: class base { public: base(){} virtual ~base(){}; virtual base *getcopy() = 0; }; template<class T> class derived:public base { public: T info; derived(T a): info(a){} virtual ~derived(){} virtual base *getcopy() { return (new derived<T>(info)); } }; base *content; template<class T> MyAny(const T a): content(new derived<T>(a)){} MyAny(): content(NULL){} MyAny(const MyAny &A) { content = (A.content)->getcopy(); } ~MyAny() { if(content != NULL) delete content; } MyAny& operator=(const MyAny &A) { if(content != NULL) delete content; content = (A.content)->getcopy(); return *this; } }; template<class T> T MyAny_cast(MyAny &A) { return (static_cast<MyAny::derived<T> * >(A.content))->info; } template<class T> T *MyAny_cast(MyAny *A) { if(typeid(*(A->content->getcopy())) != typeid(MyAny::derived<T>)) return NULL; else { return &((static_cast<MyAny::derived<T>* >(A->content))->info); } } int main() { while(true) { int n; string s; cin >> n >> s; if ( n == 0) break; MyAny a = n; cout << MyAny_cast<int>(a) << endl; a = s; cout << MyAny_cast<string>(a) << endl; a = MyClass(n+1); MyAny b = n + 2; MyAny * p = new MyAny(MyClass(n+3)); MyAny c = MyClass(n+4); c = * p; b = * p; delete p; MyAny d = b; MyAny_cast<MyClass>(&a)->f(); MyAny_cast<MyClass>(&b)->f(); MyAny_cast<MyClass>(&c)->f(); MyAny_cast<MyClass>(&d)->f(); c = s + "OK"; cout << MyAny_cast<string>(c) << endl; int * pi = MyAny_cast<int> ( & c); if( pi == NULL) cout << "not a int" << endl; else cout << "the int is " << * pi << endl; string * ps = MyAny_cast<string> ( & c); if( ps == NULL) cout << "not a string" << endl; else cout << "the string is " << * ps << endl; } }