動的に型サイズを求めるスマポ
http://d.hatena.ne.jp/okzk/20060622#1150958620
から。動的にサイズを調べるのは以下のようなコードはどうでしょうか。先に言っておくと冗談です。 GCC と cl.exe で確認。たぶんきっと他でもだいたい動きますおそらく。
template<class T> class smart_ptr {
T* p_;
int size_;
static int size_of(void* vp) {
char* p = (char*)vp;
void* vt = *(void**)p;
for (p++; vt != *(void**)p; p++);
return p-(char*)vp;
}
public:
explicit smart_ptr(T* p) : p_(p) {
#if 0 // 落ちる
size_ = sizeof(T);
#else // 問題なし
size_ = size_of(p);
#endif
}
T& operator[](int i) {
return *(T*)((char*)p_+size_);
}
};
#include <iostream>
using namespace std;
class Base {
public:
virtual int get_val() {return 0;}
virtual ~Base(){}
};
class Derived : public Base {
int dmy;
public:
virtual int get_val() {return 1;}
virtual ~Derived(){}
};
void print_val(Base* base, int size) {
smart_ptr<Base> p(base);
for (int i = 0; i < size; ++i)
cout << p[i].get_val() << endl;
}
int main() {
Base base[2];
print_val(base, 2);
Derived derived[4];
print_val(derived, 4);
return 0;
}仮定している内容は以下のこと。
- 仮想関数の無いクラスはたぶん使えない。
- smart_ptr のコンストラクタに渡したポインタは全て同じ型。
- 仮想関数テーブルがクラスの先頭にある。
- 配列サイズは2以上。
一個目の制限は、仮想関数のあるクラスか無いクラスか、は判定できる気がする…ので、解除できる気がしますが、ただのネタですし、なんかしんどいので省略。あと、テストとかいい加減なので間違ってるかも。