- 追加された行はこの色です。
- 削除された行はこの色です。
[[FrontPage]]
* C++
#contents
** template
* template
- ヘッダとソースを分ける(明示的なインスタンス化)
-- http://www.fides.dti.ne.jp/~oka-t/cpplab-template-3.html
- template <typename T> typedef T1<T2<T> > T12<T> なことについて
-- http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdndeepc/htm/deep08032000.asp
-- [[http://www.microsoft.com/japan/msdn/library/...>http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdndeepc/htm/deep08032000.asp]]
-- とりあえず typedefのテンプレートはできない
** stringstream
* stringstream
- strstream の新しい版?
- #include <sstream>
** string::resize
* string::resize
"\0\0..." になってる?
** コンストラクタとg++(3.3.5)とboost::shared_ptrな怪しい関係
* コンストラクタとg++(3.3.5)とboost::shared_ptrな怪しい関係
どれが悪いのかわからんが
class Foo
{
boost::shared_ptr<Qux> member;
Foo(Bar bar)
{
Foo(bar.baz());
// ここで失敗する
ASSERT(member.get());
}
Foo(Baz baz)
{
member.reset(new Qux());
}
};
init(Baz)とか言うメソッドを作って Foo(Baz)の処理をそのまま移せば問題なし。
* オーバーロードは動的ではない
callFoo は引数の表面上の方で呼ばれる。
#include <iostream>
using namespace std;
class Base
{
public:
virtual void foo()
{
cout << "Base::foo()" << endl;
}
};
class Derived : public Base
{
public:
virtual void foo()
{
cout << "Derived::foo()" << endl;
}
};
void callFoo(Base &base)
{
cout << "callFoo(Base &)" << endl;
base.foo();
cout << endl;
}
void callFoo(Derived &derived)
{
cout << "callFoo(Derived &)" << endl;
derived.foo();
cout << endl;
}
int main()
{
Base b;
Derived d;
Base *ptr = &d;
Base &ref = d;
callFoo(b);
callFoo(d);
callFoo(*ptr);
callFoo(ref);
}
callFoo(Base &)
Base::foo()
callFoo(Derived &)
Derived::foo()
callFoo(Base &)
Derived::foo()
callFoo(Base &)
Derived::foo()
* オーバーロードと デフォルト引数と char*
void foo(const std::string &str, bool flag=false);
void foo(bool flag=false);
char *p;
foo(p);
char*はstd::stringではなくboolとしてみられるので後者が呼ばれる。~
g++ 3.3.6~
* string iterator not dereferencable
VC++2005で下記のような終端チェックは string iterator not dereferencable といって落ちる。~
// だめ
*it == '\0'
// 正解
it == original.end()
ここで original が出てくるのがなんとかならんかな。
* 親クラスを引数に取るコンストラクタとコピーコンストラクタの罠
class LinkedTimer : public ITimer
{
public:
LinkedTimer(const ITimer &timer);
private:
LinkedTimer(const LinkedTimer &rhs);
};
コピーコンストラクタを潰していると、上のコンストラクタを呼んでいるつもりでコンパイルエラー。~
コピーコンストラクタを定義しなければデフォルトのコピーコンストラクタが作られてハマりそう。
* 初期化子の順番
初期化子の呼ばれる順はメンバを定義した順番であって、~
初期化子の書いてある順番ではない。
* placement new/delete
** アロケータの使用
// 全てのファイルに include される必要がある
// NEW_DELETE_HEAP が事前に定義される必要がある
inline void *operator new(u32 size) {return NEW_DELETE_HEAP.alloc(size);}
inline void *operator new[](u32 size) {return NEW_DELETE_HEAP.alloc(size);}
inline void operator delete(void *block) throw() {NEW_DELETE_HEAP.free(block);}
inline void operator delete[](void *block) throw() {NEW_DELETE_HEAP.free(block);}
** 確保済みのメモリ使用
配列に個別に引数付きコンストラクタを指定したいときなど
#include <new>
Foo *foo = (Foo*)alloc(sizeof(Foo));
new(foo) Foo();
foo->~Foo();
free(foo);
* 非ローカル静的変数の初期化順序、の制御
翻訳単位が違うと通常初期化順序は不定。~
仕様も真っ黒だが、対処も黒魔術。~
関数で、static ローカル変数をラップする対処などが王道。
// Visual Studio
// user|lib|compiler というグループ単位
#pragma init_seg(user)
Object o;
// g++
// N が小さいほど優先
// u16
__attribute__((init_priority(N)))