compiling trouble


河原林研究室>>ワンマン的日記>>compiling trouble

コンパイルトラブル

このページでは、以下のような問題に対して、言及する。

コンパイルができない(コンパイルエラー)
コンパイルは通ったが、実行時エラーが出る
コンパイルは通ったが、思い通りに動かない

セグメンテーション違反

よく起こること

配列の要素数をこえるインデックス値を指定してしまう。

	int a[10];
	a[10] = 23;    // NG

(あるオブジェクトのインスタンスのつもりが、)NULLにたいしてメンバ(変数/関数)を呼び出してしまう。

	Object obj = NULL;
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.print();    // NG

すでに死んでいるインスタンスへのポインタからメンバ(変数/関数)を呼び出してしまう。

	Object *o = getObjectPointer();
	o->print();    // NG
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	Object* getObjectPointer()
	{
	    Object obj( "local object" );
	    return &obj;
	}

ポインタトラブル

メンバ関数のポインタを使おうとしたら error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘f (...)’

メンバ関数へポインタを用いて関数を呼び出そうとしたが、コンパイルで下記のエラーが出る。

  • error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘f (...)’
	typedef string (Object::*F)(string)
	F f = &Object::func;
       string result = (this->*f)( "aaa" );        //OK
       //string result = this->*f( "aaa" );        //NG

this->*f( "aaa" )のほうでは、解釈が曖昧になりコンパイルを通らない。

informative discussion : http://www.gamedev.net/community/forums/topic.asp?topic_id=528416

オブジェクトのコピー

共通の親クラスをもつ派生クラスの実体を配列で管理しようとして。。。

cf.共通の親クラスをもつ派生クラスのポインタを配列で管理する。

Object親クラス
SubObject1派生クラス
SubObject2派生クラス
	Object *obj[3];
	
	obj[0] = new Object();
	obj[1] = new SubObject1();
	obj[2] = new SubObject2();
	
	for( int i=0; i<3; i++ )
	{
	    obj[i]->print();
	}

この例では、それぞれのクラスで定義されたprintが呼び出される。


一方、 cf.共通の親クラスをもつ派生クラスの実体を配列で管理(しようと)する。

	Object obj[3];
	
	Object o1;
	SubObject1 o2;
	SubObject2 o3;
	
	obj[0] = o1;
	obj[1] = o2;
	obj[2] = o3;
	
	for( int i=0; i<3; i++ )
	{
	    obj[i].print();
	}

この例では、すべてObjectクラスのprintが呼び出される。

[solution]
どうしても、実体で管理したいのだーという場合。

	class SomeObject {
	
	private:
	    Object *obj;
	
	public:
	    template <class X> void setObj( X* a )
	    {
	          /* 
	            オブジェクトのポインタを受け取りコピー処理を行うコンストラクタ(X(a))
	            を用いて生成されたオブジェクト(X)のポインタをobjが受け取る。
	         */
	          obj = new X( a );    // コピーコンストラクタではない。
	
	    }
	
	    void print()
	    {
	        obj->print();
	    }
	
	};
	
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	SomeObject obj[3];
	
	Object o1;
	SubObject1 o2;
	SubObject2 o3;
	
	obj[0].setObj( &o1 );
	obj[1].setObj( &o2 );
	obj[2].setObj( &o3 );
	
	for( int i=0; i<3; i++ )
	{
	    obj[i].print();
	}

(何か他にいい方法もあるんかもしれんけど、)知らぬ間に実体が死んでいることを防ぐために
実体としてデータが同じものをコピーしてしまうソリューション。~

参考