クラスの複製…。

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

クラスの複製…。

#1 投稿記事 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)
高信期

#2 投稿記事 by 高信期 »

クラスの生成、廃棄にはNew、delete演算子を使えばコンストラクタ、デストラクタが呼び出されますよ。
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

#3 投稿記事 by 7 »

返信ありがとうございます。

すみません。問題の解決法ではなく問題そのものはないでしょうか?
プログラムは滞りなく動くんですが、自分には想像しえない問題が起きてるんじゃないかと思い質問しました。
適当に書いたら動いたコードなので問題なしという確信が持てません…。
マティ
記事: 161
登録日時: 2005年8月23日(火) 00:15
お住まい: 沖縄県
連絡する:

#4 投稿記事 by マティ »

一見動作しているように見れるのですが・・・
calloc(size)で取得した領域はデータ領域です。
プログラム(関数)を実行すると不具合がでる可能性があります。
マティ
記事: 161
登録日時: 2005年8月23日(火) 00:15
お住まい: 沖縄県
連絡する:

#5 投稿記事 by マティ »

動作を実験しましたが、特に問題は発生しませんでした。 Dim test As CTest()()を取った方が良いと思います。
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

#6 投稿記事 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
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

#7 投稿記事 by 7 »

calloc()関数でも問題ありませんでしたか(^_^;)

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

#8 投稿記事 by 高信期 »

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

ABでもこのような内部仕様になるとも限らないので、
クラス生成、廃棄にはNew,Delete演算子を使用するのが無難かもしれません。
マティ
記事: 161
登録日時: 2005年8月23日(火) 00:15
お住まい: 沖縄県
連絡する:

#9 投稿記事 by マティ »

> calloc()関数でも問題ありませんでしたか(^_^;)
現在の仕様では動くようですって事で、ご理解下さい。

自分は、New 演算子で作成するロジックを推奨します。
※将来的にクラスの機能は向上しますので、要注意って事です。
 
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#10 投稿記事 by イグトランス »

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

また、近頃のVC++のmalloc/freeなどは単にHeapAlloc/HeapFreeを呼ぶようになっています。
HeapAllocを使わなくても結局やっていることは同じようなものです。
ならばどうせWindowsのものを使えば良いではないかという方向にVC++の開発者がなったのではないでしょうか。
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

#11 投稿記事 by 7 »

なるほど。クラスを複製する際の生成、破棄もNew,Delete演算子にします。
えーと、一応これでお終いにしたいと思います。ありがとうございました。

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

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