ページ 11

new クラス; とは

Posted: 2013年2月04日(月) 02:47
by sg kt
長いですが…

コンストラクタとnewについてよくわかりません.
下のコードを実行したところ,

コード:


class CClass1 {
	public:
	CClass1(){
		cout << "CClass1 co" << endl;
	}
	~CClass1(){
		cout << "CClass1 de" << endl;
	}

	void func(){return;}

	int v,u;
	static const int c=5;
};

class CClass2 {
	public:
	void* operator new(size_t t){return 0;}
	void operator delete(void* p){}

	CClass2(){
		cout << "CClass2 co" << endl;
	}
	~CClass2(){
		cout << "CClass2 de" << endl;
	}
};

int main(void){
	CClass1 c1;
	CClass2 c2;

	cout << "1" << endl;

	CClass1* pc1 = new CClass1;
	CClass2* pc2 = new CClass2;

	cout << "2" << endl;

	CClass1* pc3 = new CClass1();
	CClass2* pc4 = new CClass2();

	cout << "3" << endl;

	delete pc1;
	delete pc2;

	return 0;
}
このように出力されます
CClass1 constractor
CClass2 co
1
CClass1 constractor
2
CClass1 constractor
3
CClass1 destractor
このことから,newでコンストラクタが呼ばれていると推測できます.

さらに,下のコードを実行したところ

コード:

char buffer[500];

class CClass2 {
	public:
	void* operator new(size_t t){return &buffer;}
	void operator delete(void* p){}

	CClass2(){
		cout << "CClass2 co" << endl;
	}
	~CClass2(){
		cout << "CClass2 de" << endl;
	}
	int i;
	int j;
};

int main(void){
	CClass2 c2;
	cout << "1" << endl;
	CClass2* pc2 = new CClass2;
	cout << "2" << endl;

	printf("&buffer, &pc2, &(pc2->i), &(pc2->j) = %p %p %p %p\n",&buffer, pc2, &(pc2->i), &(pc2->j) );

	delete pc2;

	int i; cin >> i;
	return 0;
}
このように出力されます
CClass2 co
1
CClass2 co
2
&buffer, &pc2, &(pc2->i), &(pc2->j) = 00E90218 00E90218 00E90218 00E9021C
CClass2 de
このことから,任意の場所に確保することも出来ると推測できます.
(プレースメントnewというものもあるということをこの後知りました.)

ここで疑問なのですが
  1. new CClass2()
    は,結局は
    {
    malloc( sizeof(CClass2) );
    このmallocで返る位置の後続にメンバ変数などを順におく;
    コンストラクタに書かれている処理;
    }
    と同義なのでしょうか?それ以外の働きはありますか?
    コンストラクタと,コンストラクタをnewで動的に呼んだときに何が起こるのか教えてください.
  2. もしそうなら,メンバ関数やstatic constにした定数,スーパークラス,サブクラスのそれらといった,
    複数のインスタンスで使い回されるものはメモリのどこに確保されるのですか?
  3. +, -, sizeof, new, delete はなぜわざわざ「関数」とは別の「演算子」という定義がされているのですか?
よろしくお願いします.

Re: new クラス; とは

Posted: 2013年2月04日(月) 07:01
by beatle
1.
まあ、ほとんどその3行の処理と同じと推測されます。(具体的にnewでどういう処理が行われるかは処理系まかせのはずです)
new[]を使った場合、確保される領域の先頭に要素数を格納するなどの処理が入ることもあります。

「このmallocで返る位置の後続にメンバ変数などを順におく」というのが何を意図しているのか分かりませんが、mallocでメモリを確保した段階でメンバ変数は配置済みと考えてよいのでは。
コンストラクタでは、そのメンバ変数の初期化が行われます。

2.
複数のインスタンスで使い回されるものは、普通のグローバル変数や関数内static変数と同じような場所に置かれます。
メンバ関数も、グローバル関数と同じ場所に置かれます。
メンバ関数=第一引数がthisポインタになっているグローバル関数と思えばいいんじゃないでしょうか。

3.
関数と演算子は本質的には同じもので、呼び出し方が違うだけです。
+を関数だとすると、+(1,2)のように呼び出すのですが、これは面倒。数学のように呼び出したいので演算子として扱い、1+2と書きます。
実際の所、C++では
operator +(int a, int b)
として、いかにもメンバ関数定義のような形で + 演算子をオーバーライドしたりできます。

「なぜわざわざ「関数」とは別の「演算子」という定義がされているのですか?」
うーん。C++開発者の意図(というより、元になった言語の開発者の意図)は良くわかりませんが、「括弧なしで呼び出したいから」というのが答えかなと思います。

Re: new クラス; とは

Posted: 2013年2月04日(月) 15:39
by sg kt
参考書を読んだ後,実際に色々作ってみるとまだまだ知識が甘いと実感して質問しました.
ありがとうございました.

Re: new クラス; とは

Posted: 2013年2月04日(月) 15:40
by sg kt
ほげ