ページ 11

クラスの複製…。

Posted: 2005年12月30日(金) 22:00
by 7
Aを複製して独立したBを作ろうと思い以下のプログラムを組みました。で、何か問題はないでしょうか?
自分にはコンストラクタ、デストラクタが実行されない(実行されなくて構わない)ことぐらいしか分からないのですが…。

コード: 全て選択

Class CTest
Public
	c_x As Long
	c_y As Long

	Function clone() As *CTest
	Dim size As DWord
		size=SizeOf(CTest)
		clone=calloc(size)
		memcpy(clone,VarPtr(This),size)
	End Function
End Class

Dim test As CTest()
Dim test2 As *CTest

test.c_x=100
test.c_y=200

test2=test.clone()

test.c_x=test.c_x*2
test.c_y=test.c_y*2

Debug

free(test2)

Posted: 2005年12月30日(金) 22:18
by 高信期
クラスの生成、廃棄にはNew、delete演算子を使えばコンストラクタ、デストラクタが呼び出されますよ。

Posted: 2005年12月30日(金) 22:51
by 7
返信ありがとうございます。

すみません。問題の解決法ではなく問題そのものはないでしょうか?
プログラムは滞りなく動くんですが、自分には想像しえない問題が起きてるんじゃないかと思い質問しました。
適当に書いたら動いたコードなので問題なしという確信が持てません…。

Posted: 2005年12月30日(金) 22:58
by マティ
一見動作しているように見れるのですが・・・
calloc(size)で取得した領域はデータ領域です。
プログラム(関数)を実行すると不具合がでる可能性があります。

Posted: 2005年12月30日(金) 23:09
by マティ
動作を実験しましたが、特に問題は発生しませんでした。 Dim test As CTest()()を取った方が良いと思います。

Posted: 2005年12月30日(金) 23:29
by 7
なるほど。calloc()関数だと不具合がでる可能性があるのですね。ちょっとコードを書き直しました。
コンストラクタ、デストラクタが実行されたのでこちらの方が良いかな、と思いました。

コード: 全て選択

Class CTest
Public
	c_x As Long
	c_y As Long

	Function clone() As *CTest
	Dim size As DWord
		size=SizeOf(CTest)
		clone=New CTest()
		memcpy(clone,VarPtr(This),size)
	End Function
End Class

Dim test As CTest()
Dim test2 As *CTest

test.c_x=100
test.c_y=200

test2=test.clone()

test.c_x=test.c_x*2
test.c_y=test.c_y*2

Debug

Delete test2

Posted: 2005年12月30日(金) 23:35
by 7
calloc()関数でも問題ありませんでしたか(^_^;)

> Dim test As CTest()()を取った方が良いと思います。
コンストラクタに引数がないことを明示的にするつもりで書いていたのですが以後気を付けます。
同様に、clone=New CTest()()も取った方が良いですよね。

Posted: 2005年12月31日(土) 00:00
by 高信期
>すみません。問題の解決法ではなく問題そのものはないでしょうか?
失礼いたしました。
他言語の話になりますが、VC++ではNew演算子は内部でVirtualXX系の関数でメモリ確保しているそうです。
Win9x系でののHeapXX系の関数(ABではmalloc,calloc等で使用)は、
>4 メガバイト(MB)未満のメモリブロックを扱うように設計されています。
http://www.microsoft.com/japan/develope ... palloc.htm
なのだそうで、Win9xでも巨大メモリを手軽に使用できるよう設計されたのでしょう。

ABでもこのような内部仕様になるとも限らないので、
クラス生成、廃棄にはNew,Delete演算子を使用するのが無難かもしれません。

Posted: 2005年12月31日(土) 08:15
by マティ
> calloc()関数でも問題ありませんでしたか(^_^;)
現在の仕様では動くようですって事で、ご理解下さい。

自分は、New 演算子で作成するロジックを推奨します。
※将来的にクラスの機能は向上しますので、要注意って事です。
 

Posted: 2005年12月31日(土) 10:56
by イグトランス
またABからは逸れますが,C++ではコンストラクタ・デストラクタがないなど,
一定の要件を満たしたクラスはPODと呼ばれます。
PODはcallocなどで確保したメモリを使ったり,memcpyでコピーしたりしても良いクラスである,
――言うなればABでのType相当に扱える――ということがきちんと定められています。
これはC++での構造体とクラスの違いがないという特異性ゆえの事情もありますが。

また、近頃のVC++のmalloc/freeなどは単にHeapAlloc/HeapFreeを呼ぶようになっています。
HeapAllocを使わなくても結局やっていることは同じようなものです。
ならばどうせWindowsのものを使えば良いではないかという方向にVC++の開発者がなったのではないでしょうか。

Posted: 2005年12月31日(土) 17:05
by 7
なるほど。クラスを複製する際の生成、破棄もNew,Delete演算子にします。
えーと、一応これでお終いにしたいと思います。ありがとうございました。

> ABからは逸れますが,C++ではコンストラクタ・デストラクタがないなど,
> 一定の要件を満たしたクラスはPODと呼ばれます。
> PODはcallocなどで確保したメモリを使ったり,memcpyでコピーしたりしても良いクラスである,
ABにもそういうものがあったら悩まず解決したんでしょうね。

> また、近頃のVC++のmalloc/freeなどは単にHeapAlloc/HeapFreeを呼ぶようになっています。
ABもそのようになってるんじゃないでしょうか…?。