ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2017年11月25日(土) 08:48

All times are UTC+09:00




新しいトピックを投稿する  トピックへ返信する  [ 14 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2005年9月09日(金) 12:30 
オフライン

登録日時: 2005年5月31日(火) 10:52
記事: 264
住所: 高知
引用:
> ユーザーの皆様、COMの取り扱い方についてちょっとご相談。
> AB4では、C++のそれと同じように、仮想関数を定義することでCOMインターフェイスを定義しています。しかし、実体を持つクラス(ここでは、メンバ変数を持つという意味)を多重継承できないなど、ちょっとした制約があることも事実です。
私はC++は仮想関数では無く、純粋仮想関数を使ってインターフェイスを定義していると理解しているのですが、、、
ActiveBasicも純粋仮想関数を導入してはどうですか?

C++のインターフェイスで関数の後に=0がついているのが純粋仮想関数
コード:
virtual HRESULT Hoge(DWORD dw) = 0;
C++ではvirtual指定があっても、後に=0が付くか付かないかで
仮想関数か純粋仮想関数かになります。
山本様もご承知の通り、この二つは別物です。

※もしかして、
ABの仮想関数がC++でいうところの純粋仮想関数なのでしょうか?

引用:
> また、仮想関数とインターフェイスメソッドの違いなども問題になっています。コンパイラが生成する仮想関数は、オブジェクトのThisポインタがecxレジスタを介して渡されますが、インターフェイスメソッドへのインターフェイスポインタの引き渡しはスタックを介して行われます。細かい部分ですが、コーディング作法にも影響してくるところなので、ちょっと気になる点です。
OLEドロップの細かい挙動がおかしくなるのもこの影響なんですね?
まぁ、詳しくは分からないので何とも言えませんが。。。

引用:
Interfaceステートメントは、複数のインターフェイスの実装を可能にするつもりです。
>
> あと、Classステートメントで定義される仮想関数のフリをしたインターフェイスについてですが、Interfaceステートメントを導入したら、廃止しようと思います。まぁ、クラスの仮想関数がインターフェイスとして使えなくかもしれないってことです。
>
> 何かご意見、アドバイスなどありましたらご返信願います。

いろいろオブジェクト指向の周りを整備していこうとしているのであれば
追加すべき事柄がたくさんありますよ。

たとえば、現状ではインターフェイスIDをユーザが構造体変数として自力で
定義しないといけなくなっています。
ですのでCでいうところのexturnなんぞを導入して
GUID型の特定の名前の変数を定義したら自動的に初期化してくれるような
機能が必要ですし、
今のようにずらずらとClass~End Class間にメンバ関数を定義していく状態だとかなり大変なことになりますよね。
これらはポリモーフィズム以前の問題です。
あとはブログにもあったようにvtableの上書きですね。

とにかく、問題が山積みだと思いますので
頑張ってください。



P.S.
他にも欲しい機能がありました。
・クラス内にスタティックメンバを入れられるとか
・フレンドクラスとか
・関数のオーバーロード←絶対必要

これじゃきり無いな。。。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年9月09日(金) 19:32 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 895
住所: 東京都
私はInterfaceには賛成です。
そして、それとは別に仮想関数に対する純粋仮想関数(抽象メソッド/Abstruct, Prue, = 0など構文・用語はともかく)を将来的には用意してほしいと思っています。
(クラスの多重継承をできるようにするかどうかとは無関係に)
純粋仮想関数の用途は大きくこの2つに分類できるので用途別に構文も2つにわけた方が良い、と思っているからです。

> ・関数のオーバーロード←絶対必要
個人的には密かに型チェックの厳格化はこのための布石ではないかと思っています。
ついでに演算子の多重定義があればStringを特別扱いからただのクラスにできますね。
少なくともoperator =だけは早期に導入したほうがいいのではと思います。

 話はそれますが。
> Function QueryInterface(riid As *GUID, ppvObj As DWordPtr) As DWord
riidはByRefにしませんか。Interfaceを導入するときについでにやってしまえばいいと思います。(それともByRefは使わない方針でしたっけ?)


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年9月10日(土) 16:06 
オフライン
Site Admin

登録日時: 2005年5月30日(月) 15:08
記事: 535
NoWestさん、イグトランスさん、アドバイス助かります。

引用:
私はC++は仮想関数では無く、純粋仮想関数を使ってインターフェイスを定義していると理解しているのですが、、、ActiveBasicも純粋仮想関数を導入してはどうですか?
双方を導入する予定です。構造的には、VC++と同等のものを用意したいのですが、構文のほうが悩ましいところです。単純に、インターフェイスでは純粋仮想関数のみを利用することがわかっていれば、
コード:
Interface IUnknown
    Function QueryInterface(riid As *GUID, ppvObj As DWordPtr) As DWord
    Function AddRef() As DWord
    Function Release() As DWord
End Interface
このような構文を下記のようにコンパイラが解釈すればよいということになります。
コード:
Class IUnknown
Public
    Pure Virtual Function QueryInterface(riid As *GUID, ppvObj As DWordPtr) As DWord
    Pure Virtual AddRef() As DWord
    Pure Virtual Release() As DWord
End Interface
"Pure"が先頭に付くことで、そのメンバ関数が純粋仮想関数であることを示し、プロトタイプ宣言という扱いになります。

"Virtual"のみの場合は、実装と共に定義される仮想関数になります。

何もつかない場合は、通常のメンバ関数になります。

引用:
※もしかして、
ABの仮想関数がC++でいうところの純粋仮想関数なのでしょうか?
お察しの通り、AB4で"Virtual Function"と定義されているものはすべて純粋仮想関数です。実装は定義できません。しかも、現状ではサブクラスでのオーバーライドもできていません(現状では、通常のメンバ関数のみ、オーバーライド可能となっています)。

仮想関数のオーバーライド機能はかなり重要なものになってくることは認識しておりますので、構文案がまとまり次第、実現させようと思います。

引用:
たとえば、現状ではインターフェイスIDをユーザが構造体変数として自力で
定義しないといけなくなっています。
ですのでCでいうところのexturnなんぞを導入して
GUID型の特定の名前の変数を定義したら自動的に初期化してくれるような
機能が必要ですし、
今のようにずらずらとClass~End Class間にメンバ関数を定義していく状態だとかなり大変なことになりますよね。
こいつは、VC++で言う、"#import"に相当する機能ですよね。外部インターフェイスと連携を取るプログラムを書き場合は、絶対に必要ですね。

COMで機能を提供しているDLLの内容を読み取り、インターフェイス周りの識別子情報を取得するためのプログラムを書けば、実現できそうですが、こちらはこれから資料集めです/(--)/

引用:
・クラス内にスタティックメンバを入れられるとか
・フレンドクラスとか
・関数のオーバーロード
どれも重要な要素ですので、順に追加していこうと思います。関数のオーバーロード、早めに実装できるようにしますので、今しばらくお待ちください。演算子のオーバーロードもなるべく早めに…

引用:
そして、それとは別に仮想関数に対する純粋仮想関数(抽象メソッド/Abstruct, Prue, = 0など構文・用語はともかく)を将来的には用意してほしいと思っています。
(クラスの多重継承をできるようにするかどうかとは無関係に)
純粋仮想関数の用途は大きくこの2つに分類できるので用途別に構文も2つにわけた方が良い、と思っているからです。
具体的には、仮想関数、純粋仮想関数の仕分けを記述できる構文("Pure"指定)を導入すると共に、Interfaceステートメントの導入を検討しています。

Interfaceステートメントは、Classステートメントの構文仕様の関係でインターフェイス定義が冗長的にならないよう、プリプロセッサ的な働きをするものです。ようは、よりスマートにパブリックな純粋仮想関数を定義できるってことですな。

引用:
Function QueryInterface(riid As *GUID, ppvObj As DWordPtr) As DWord
riidはByRefにしませんか。Interfaceを導入するときについでにやってしまえばいいと思います。(それともByRefは使わない方針でしたっけ?)
ウーン、どっちが妥当なんでしょうか…。ポインタを隠そうとする昨今の言語事情を考慮すれば、「参照型」を積極的に活用していくことは非常に大きな意味を持つことになると思います。しかし、ABはシステム記述型の特性をもつ、C/C++の派生言語のような構造をしているんですよね。こうなると、ポインタベースの仕様が一番自然にはなってくるのですが…。

私は、C/C++のような、コアな技術者向けのスマートなコーディング作法が好きですが、それと同時に生産性を向上させるようなJava/C#的なコーディング作法にも非常に関心を持ちます。

結局のところ、こういう細かいところを今後どうしていくのかは、まだ考え中といった段階です。裏づけになるいい資料、「こういうところを勉強しなよ~」といったところがありましたら、引き続き、アドバイスをいただけると助かります。


通報する
ページトップ
投稿記事Posted: 2005年9月10日(土) 22:32 
オフライン

登録日時: 2005年6月04日(土) 10:09
記事: 72
引用:
引用:
Function QueryInterface(riid As *GUID, ppvObj As DWordPtr) As DWord
riidはByRefにしませんか。Interfaceを導入するときについでにやってしまえばいいと思います。(それともByRefは使わない方針でしたっけ?)
ウーン、どっちが妥当なんでしょうか…。ポインタを隠そうとする昨今の言語事情を考慮すれば、「参照型」を積極的に活用していくことは非常に大きな意味を持つことになると思います。しかし、ABはシステム記述型の特性をもつ、C/C++の派生言語のような構造をしているんですよね。こうなると、ポインタベースの仕様が一番自然にはなってくるのですが…。
ここはCOMの、というよりC++の記述に従うのが適切かと思います。
C++では
コード:
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
というふうになりますが、ここでREFIIDは
コード:
#define REFIID const IID &
と定義されてるので、参照渡しです。どうやら入力の引数(メソッドに渡す)は値渡しや参照渡し、出力の引数(メソッドから受け取る)はポインタ渡しとなっているみたいです。(ただし、インターフェイスへのポインタはインターフェイスポインタ型とでもいうべき独立な型として扱っている。)

引用:
コード:
Class IUnknown
Public
    Pure Virtual Function QueryInterface(riid As *GUID, ppvObj As DWordPtr) As DWord
    Pure Virtual Function AddRef() As DWord
    Pure Virtual Function Release() As DWord
End Interface
"Pure"が先頭に付くことで、そのメンバ関数が純粋仮想関数であることを示し、プロトタイプ宣言という扱いになります。
"Virtual"のみの場合は、実装と共に定義される仮想関数になります。
何もつかない場合は、通常のメンバ関数になります。

具体的には、仮想関数、純粋仮想関数の仕分けを記述できる構文("Pure"指定)を導入すると共に、Interfaceステートメントの導入を検討しています。
Interfaceステートメントは、Classステートメントの構文仕様の関係でインターフェイス定義が冗長的にならないよう、プリプロセッサ的な働きをするものです。ようは、よりスマートにパブリックな純粋仮想関数を定義できるってことですな。
純粋仮想関数の構文案が挙がっていますが、イグトランスさんが示したAbstractが簡潔でいいかな~?と思います。
無論、Pure Virtualの方が構文解析上都合がよい、あるいは"純粋"、"仮想"の名にふさわしいなどの理由なら、こちらの方が良いですが。(^^;
Abstractだと抽象メソッドと呼んだ方が良いですね。



それから、
引用:
また、仮想関数とインターフェイスメソッドの違いなども問題になっています。コンパイラが生成する仮想関数は、オブジェクトのThisポインタがecxレジスタを介して渡されますが、インターフェイスメソッドへのインターフェイスポインタの引き渡しはスタックを介して行われます。細かい部分ですが、コーディング作法にも影響してくるところなので、ちょっと気になる点です。
とのことですが、つまりCOMインターフェイスの仕様と、ABの純粋仮想関数(現在のVirtual指定)の仕様が異なるということですよね。
だとするとABで実装予定のInterfaceステートメントはCOMインターフェイスとしてしか使えないのでしょうか?
というのは、Javaにあるような言語仕様内で使えるポリモフィズムや多重継承を実現するためのインターフェイスがあると分かりやすいと思うからです。
引用:
引用:
私はC++は仮想関数では無く、純粋仮想関数を使ってインターフェイスを定義していると理解しているのですが、、、ActiveBasicも純粋仮想関数を導入してはどうですか?
双方を導入する予定です。構造的には、VC++と同等のものを用意したいのですが、構文のほうが悩ましいところです。
Interfaceステートメント内のメソッドがC++と同等の純粋仮想関数とみなされるのであれば、この要求は満たされるとは思いますが..


最後に編集したユーザー Tomorrow on 2005年9月23日(金) 00:16 [ 編集 1 回目 ]

通報する
ページトップ
投稿記事Posted: 2005年9月10日(土) 23:58 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 895
住所: 東京都
引用:
引用:
Function QueryInterface(riid As *GUID, ppvObj As DWordPtr) As DWord
> riidはByRefにしませんか。Interfaceを導入するときについでにやってしまえばいいと思います。(それともByRefは使わない方針でしたっけ?)
> ウーン、どっちが妥当なんでしょうか…。ポインタを隠そうとする昨今の言語事情を考慮すれば、「参照型」を積極的に活用していくことは非常に大きな意味を持つことになると思います。しかし、ABはシステム記述型の特性をもつ、C/C++の派生言語のような構造をしているんですよね。こうなると、ポインタベースの仕様が一番自然にはなってくるのですが…。
QueryInterfaceのインターフェイスIDは今のところポインタ渡しです。
そのため呼ぶときにはVarPtr(IID_なんとか)とする必要があります。
するとこれがポインタ渡しだと実感できます。しかし、ここでポインタ渡しだと実感しても何のありがたみもありません。
本来は値渡しで十分なのですが、ポインタ・参照渡しのほうが効率が良いので使っているだけに過ぎないからです。
なので呼び出し時に値渡し同様に書ける参照渡しが良いと私は思うわけです。
引用:
引用:
引用:
私はC++は仮想関数では無く、純粋仮想関数を使ってインターフェイスを定義していると理解しているのですが、、、ActiveBasicも純粋仮想関数を導入してはどうですか?
> 双方を導入する予定です。構造的には、VC++と同等のものを用意したいのですが、構文のほうが悩ましいところです。
> Interfaceステートメント内のメソッドがC++と同等の純粋仮想関数とみなされるのであれば、この要求は満たされるとは思いますが..
私は前述のとおりインターフェイスとは別に抽象メソッドとしての純粋仮想関数は必要と思っています。


通報する
ページトップ
投稿記事Posted: 2005年9月11日(日) 12:43 
オフライン

登録日時: 2005年5月31日(火) 10:52
記事: 264
住所: 高知
引用:
Function QueryInterface(riid As *GUID, ppvObj As DWordPtr) As DWord
密かにこのメソッドの第2引数はポインタのポインタなので
値を取り出すには
コード:
Dim a As *IHoge
a=GetDWord(ppvObj)
最新のActiveBasicはどうなのか分かりませんが、、、
OLEドロップに挑戦している頃、結構これが面倒でした。
最終的にByRef指定のVoidPtrという引数していましたが。。。
引用:
Absuructだと抽象メソッドと呼んだ方が良いですね。
Abstructは響きがいいですね。
ただ、あまり馴染みの無い単語ではありますが、、、



話は変わりますが、、、

少し前に書き込んで未だご意見を伺っていないことがあるんですが
UNICODEへの対応はどうなっているのでしょうか?


通報する
ページトップ
投稿記事Posted: 2005年9月13日(火) 17:55 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 895
住所: 東京都
引用:
引用:
また、仮想関数とインターフェイスメソッドの違いなども問題になっています。コンパイラが生成する仮想関数は、オブジェクトのThisポインタがecxレジスタを介して渡されますが、インターフェイスメソッドへのインターフェイスポインタの引き渡しはスタックを介して行われます。細かい部分ですが、コーディング作法にも影響してくるところなので、ちょっと気になる点です。
とのことですが、つまりCOMインターフェイスの仕様と、ABの純粋仮想関数(現在のVirtual指定)の仕様が異なるということですよね。
だとするとABで実装予定のInterfaceステートメントはCOMインターフェイスとしてしか使えないのでしょうか?
というのは、Javaにあるような言語仕様内で使えるポリモフィズムや多重継承を実現するためのインターフェイスがあると分かりやすいと思うからです。
インターフェイスを実装するクラスでは、インターフェイスの関数に対してはThisをスタックに置くStdCallにして、その他の関数にはThisをecxレジスタに置くThisCall(仮称)を使うというので問題があるのでしょうか?
コード:
Class Base
Public
	Virtual Sub Print()
		Print "Hallo"
	End Sub
End Class

Interface IPrint
	Sub Print()
End Interface

Class Derived
	Inherits Base
	Implements IPrint
End Class
(構文は想像を交えてあります)
こういう例では問題になります。しかし面倒ですが、DerivedのIPrintのPrintにはStdCall→ThisCallへ変換してBaseのPrintを呼ぶサンクを置けばいいのではないかと思いました。

#考えるだけならいくらでもできるんですけどね


通報する
ページトップ
投稿記事Posted: 2005年9月18日(日) 21:38 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 895
住所: 東京都
引用:
5. 関数のオーバーロードが可能
パラメータ特性が異なれば、同じ名前の関数(またはメソッド)を複数定義できるようになります。関数呼び出し側は、指定されたパラメータの特性を判断し、適切な関数を呼び出します。

関数をオーバーライドするときは、2つ目以降の関数の定義文にOverride修飾子を付けなければなりません。Override修飾子をつけずに、重複した関数名を定義しようとするとエラーになります(この仕様はミスを防ぐためのものです)。
AB Ver4.2で実施するポリモフィズム対策のページにこのような文章がありますが、これではオーバーライドとオーバーロードを混同して書かれてしまっているように思ってしまいます。
Override識別子は抽象メソッドのところで扱っているので重複していますよね。

それともまさかOverloadなんて導入するのでしょうか?


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年9月19日(月) 21:22 
オフライン
Site Admin

登録日時: 2005年5月30日(月) 15:08
記事: 535
まず、パラメータの参照方法についてですが、参照型(ByRef)が妥当な箇所は、ポインタ型を経由せずに素直にByRef扱いにしてやったほうがよさそうですね。メジャーバージョンアップでタイミングを見計らってライブラリを整理する必要がありそうです。

引用:
少し前に書き込んで未だご意見を伺っていないことがあるんですが
UNICODEへの対応はどうなっているのでしょうか?
対応できなくて申し訳ありませんでしたm(__)m
UNICODE、早めに対応したいです。知識不足ながら、UNICODEへの対応方法を勉強中です。下記のような手順でいけるんでしょうか??

1. リテラル文字列を内部でUNICODEとして扱う。
2. 文字列関連の標準関数、及びAPI関数をUNICODE対応のものへと書き換える。

1番目の事項は一時間で終わるのでいいとして、問題は2番目ですね。ASCIIとは別に、新たにライブラリを用意しなければなりません。NameSpaceあたりを取り入れて、うまくやりくりすれば案外とキレイにUNICODEライブラリを追加できるかもしれません…。

引用:
AB Ver4.2で実施するポリモフィズム対策のページにこのような文章がありますが、これではオーバーライドとオーバーロードを混同して書かれてしまっているように思ってしまいます。
Override識別子は抽象メソッドのところで扱っているので重複していますよね。
そうですそうですf(^^;;;。通常の関数(クラスに属さない関数)のオーバーロード時にOverride修飾子を使えというのは、矛盾しておりますね。

修飾子が必要だという旨の文をページ内容から削除しておきました。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年9月19日(月) 22:35 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 895
住所: 東京都
引用:
まず、パラメータの参照方法についてですが、参照型(ByRef)が妥当な箇所は、ポインタ型を経由せずに素直にByRef扱いにしてやったほうがよさそうですね。
ありがとうございます。こういう風になってほしかったのです。
引用:
少し前に書き込んで未だご意見を伺っていないことがあるんですが
UNICODEへの対応はどうなっているのでしょうか?
ええと、これはNoWestさんが書かれたものですね。たしかに私もUnicodeサポートは将来的には必要と思っていますが。
引用:
2. 文字列関連の標準関数、及びAPI関数をUNICODE対応のものへと書き換える。
VC++ではTCHARなどを使って単一ソースでマルチバイト/Unicode両対応のコードを書けるようにしていますよね。
どうやって実現するのかはともかくとしてABも単一ソースで両対応ということになるのでしょうか?
それとも原則、全ての文字をUnicodeとして扱うことになるのでしょうか?

 Overrideの件
ありがとうございます。たしかに直っていました。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年9月23日(金) 00:49 
「関数のオーバーロードが可能」にあるパラメータ特性ですが、
これはBytePtrやWordPtrのようなポインタの種類も区別されるのでしょうか?
個人的にはちゃんと区別されてほしいですね。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年9月23日(金) 02:15 
オフライン
Site Admin

登録日時: 2005年5月30日(月) 15:08
記事: 535
引用:
「関数のオーバーロードが可能」にあるパラメータ特性ですが、
これはBytePtrやWordPtrのようなポインタの種類も区別されるのでしょうか?
個人的にはちゃんと区別されてほしいですね。
内部的に厳密な型チェックが可能となっておりますので、関数のオーバーロードを実現する際は、ポインタの種別も認識できるようにする予定です。


P.S.
は~、またこんな時間まで起きていてしまった…


通報する
ページトップ
投稿記事Posted: 2005年9月26日(月) 00:35 
オフライン

登録日時: 2005年6月04日(土) 10:09
記事: 72
Ver4.2のポリモフィズム対策、拝見しました。かなりJavaに近い構文みたいで、見やすくて良いですね。
単なる誤植の指摘みたいで申し訳ないですが..
「4. インターフェイスの定義が可能」のところで
引用:
×:他は抽象メソッドと同じようなものです。例えば、下記の定義は同等です。
       ↓
○:他は抽象クラスと同じようなものです。例えば、下記の定義は同等です。
ではないでしょうか?

また、
引用:
多重継承(複数インターフェイスの実装)が可能。
とありますが、インターフェイスの実装にはJava風にImplementsキーワードとか導入するのでしょうか?
それともC系言語のように(ちょっと語弊がある..)Inheritsで共用するのですか?


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年9月27日(火) 02:53 
オフライン
Site Admin

登録日時: 2005年5月30日(月) 15:08
記事: 535
引用:
「4. インターフェイスの定義が可能」のところで
引用:
×:他は抽象メソッドと同じようなものです。例えば、下記の定義は同等です。
       ↓
○:他は抽象クラスと同じようなものです。例えば、下記の定義は同等です。
ではないでしょうか?
Tomorrowさんのご指摘通り、「抽象クラス」が正しい表現でした。早速修正しておきましたので、ご確認ください。

引用:
引用:
多重継承(複数インターフェイスの実装)が可能。
とありますが、インターフェイスの実装にはJava風にImplementsキーワードとか導入するのでしょうか?
それともC系言語のように(ちょっと語弊がある..)Inheritsで共用するのですか?
できれば、Implementsキーワードを導入したいところです。なるべく、意味的に確実なほうを選択していきたいと思っておりますので…。


通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 14 件の記事 ] 

All times are UTC+09:00


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[1人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by KONISHI Yohsuke