[[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)))


トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS