• ベストアンサー

C++で参照カウンタを実装したいのですが

こんにちは。 C++でクラスに参照カウンタを実装したいのですが、もしも実装する場合、 class CRefCounter {   参照カウンタとAddRef、Releaseメソッドを仮想メソッドとして実装 }; このクラスを継承して直接使う方法と、 class IRefCounter {   参照カウンタとAddRef、Releaseメソッドを純粋仮想メソッドとして宣言 } このクラスを継承して継承側で実装する方法とがあると思うのですが普通はどちらを使うものでしょうか?

  • 0xEF
  • お礼率59% (193/327)

質問者が選んだベストアンサー

  • ベストアンサー
  • i-kujou
  • ベストアンサー率50% (13/26)
回答No.3

IRefCounterを基底クラスに CRefCounterを作成して、CRefCounterのAddRef/Releaseを実装する。 そして、CRefCounterを継承して参照カウンターを利用するクラスを実装する、というのはどうでしょうか? 参照カウンターを利用する場合はIRefCounterを経由して操作するようにすれば、複数の実装を共存することも可能になります。

0xEF
質問者

お礼

参考にさせていただきます。ありがとうございました。

その他の回答 (4)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

割付け記憶域期間以外を持つオブジェクトや配列の場合はどう扱い予定なのでしょうか?

0xEF
質問者

お礼

>>割付記憶期間以外を持つオブジェクト というのはnewで確保したオブジェクト以外という意味でしょうか? それはコンストラクタをprivateにすることでCreate系のメソッドを経由させようとしていました。 配列のほうは完全に見落としていました。 自分の実装方法だといろいろ問題があるようですので、また少し考えさせていただきたいと思います。 ありがとうございました。

  • gentoo314
  • ベストアンサー率41% (15/36)
回答No.4

COM の IUnknown インターフェースや、その実装クラスを参考にされてはどうでしょうか。

0xEF
質問者

お礼

回答ありがとうございます。 IUnknownインターフェースは一度見たのですがいまいちよくわからなくて質問させていただいた次第でございます。 勉強不足ですみません。

回答No.2

 こんばんは。  う~ん。  上でも問題無いとは思いますが・・・、私が所有しているCOMの書籍では、下でした。

  • splwtr
  • ベストアンサー率16% (75/461)
回答No.1

参照カウンターは、どの時点で、参照(インクリメント、デクリメント) されるのですか?

0xEF
質問者

補足

回答ありがとうございます。 参照カウンタは自分でAddRefなどを呼び出す予定です。

関連するQ&A

  • c++でのヘッダーファイルの循環参照

     c++言語においての質問です.  A, Bという二つのクラスを作ったとします.  宣言は.h,実装は.cppで行っています. 【A.h】 class A{ //内容 public: B ConvertB(); }; 【B.h】 class B{ //内容 public: A ConvertA(); };  上のように,クラスAではクラスBを返すメソッド. クラスBではクラスAを返すメソッドを実装したいとします.  しかし,単純に 【A.h】に #include "B.h" 【B.h】に #include "A.h" などとすると当然循環参照になってエラーになりますよね? ...とは言っても, 【A.cpp】や【B.cpp】にインクルードした所で, ヘッダ側でエラーが起きてしまいます.  そこで,私の場合は... 【A.h】の先頭に class B{ConvertAで用いるメソッド}; 【B.h】の先頭に class A{ConvertBで用いるメソッド};  というようにする事でなんとかエラーを避けています.    ...しかし,この方法ではAやBのクラスの定義を修正する場合に, 2つのファイルのヘッダを書き換えなければならなくなります. A, B, C, D...などとクラスが増えていくと, 一つのヘッダーファイルに4つも5つもクラスの定義を書かなければなりませんし, クラスのメソッドの定義を一つ変えようとしただけでも, 複数のヘッダの内容をいじらないといけません.  非常に読みにくいコードになってしまうのです.  そこで,もう少しスマートに実現する方法は無いでしょうか?  JavaやC#を使えば簡単に解決するのですが...ライブラリの関係でC++を使わなければ ならないのです.  もしくは,このような相互変換?のクラスを作る場合はみなさんはどのようにして ヘッダーファイルの循環参照を避けているのでしょうか?  例えば様々な形式の色空間のクラスなどだったら... RGBクラス YCrCbクラス HSVクラス ...など  このようなクラスを作った後で,RGBをYCrCbに変換出来るようにしたり, その逆へも変換出来るようにしたいのです.  それともこのような変換が出来るクラスを作る事は間違っているのでしょうか?    よろしくお願いします.

  • 継承・実装の関係で悩んでいます。

    継承・実装の関係について悩んでいます。 ここでは、アクセス制御を考えずに、インスタンスかstaticかabstract(ここではabstract final staticやabstract classのこと)の違いで、どう継承するのか考えています。 // 継承 はメソッドのオーバーライドのことを考えます。(オーバーロードは考えない) クラスAからクラスBでオーバーライドしたメソッドは、 クラスCでさらにオーバーライドできるのでしょうか? クラスCが クラスBのクラスAからオーバーライドしたメソッド をクラスBのメソッドとして見たときに、オーバーライドすることは可能なのでしょうか? クラスA │ インスタンスフィールドA │ staticフィールドA │ │ クラスA() { } │ │ インスタンスメソッドA () { } │ staticメソッドB() { } ↓ クラスB extends クラスA │ インスタンスフィールドA // 継承 │ インスタンスフィールドB │ staticフィールドB │ │ サブクラス1() { } // コンストラクタは継承しない、super()で呼び出す │ │ インスタンスメソッドA () { } // 継承 │ │ インスタンスメソッドB () { } │ staticメソッドB () { } ↓ クラスC extends クラスB implements インタフェースD, ... ↑ インスタンスフィールドA // クラスBのフィールドを継承 │ インスタンスフィールドB // クラスBのフィールドを継承 │ インスタンスフィールドC │ staticフィールドC │ │ サブクラス2() { } │ │ インスタンスメソッドA () { } // クラスBのメソッドを継承 │ インスタンスメソッドB () { } // クラスBのメソッドを継承 │ インスタンスメソッドD () { } // インタフェースDのメソッドを実装 │ インスタンスメソッドE () { } // インタフェースDのメソッドを実装 │ │ │ インスタンスメソッドC () { } │ staticメソッドC() { } │ interface インタフェースD extends インタフェースE ↑ │ staticフィールドD // public static final │ │ インスタンスメソッドD() { } // public abstract │ インスタンスメソッドE() { } // 継承 │ interface インタフェースE staticフィールドE // public static final インスタンスメソッドE() { } // public abstract

    • ベストアンサー
    • Java
  • c# この高速化の方法あり? 2

     こんにちは、c#初心者です。  現在ライブラリを作成しているのですが、その中でちょっと問題がありそうな高速化の方法を思いついたので質問させていただきました。  継承させるクラスを作るときに、継承予定のクラスで実装するメソッドやメンバを、基のクラスでは public class Class1 {   internal virtual void Method()   {     throw new NotImplementedException();   } } // - - - - - - - - - - - - - - - - - - - - - - - - - public class Class2 {   internal override void Method()   {     //ここで実装   } } として、 このオブジェクト「sampleObj」があったとして、 if ( sampleObj is Class2 )   sampleObj.Method(); のようにすることで Class2 temp = sampleObj as Class2; if ( temp != null )   temp.Method(); や if ( sampleObj is Class2 )   ((Class2)sampleObj).Method(); のようにすることよりも若干高速になるようです。  末端のアプリケーションならまだ問題になりにくいかもしれませんが、今回はライブラリということなので気になっています。  気休め程度に「internal」になっていますがそれでもまずい気がします。  どなたか詳しい方がいらっしゃいましたら教えていただけませんか?

  • 【C++】継承しながら、インプリメント。

    VB.netでは、以下のように継承しつつ実装ができると思いますが、 (1)C++ では、できないのでしょうか? (2)Java では、できないのでしょうか? Class SampleClass Inherits BaseClassHoge Implements InterfaceFoo また、 Implements は、Javaでは可能ではありますが、 C++ には「Implements」はないのでしょうか? (C++ では純粋仮想関数の集合となるアブストラクトクラスを継承するという方法しかできないのでしょうか?) .

  • 【C#】内部だけで有効なインターフェースを作りたい

    C#2005でコンポーネントを作ろうと思っています。 そこであらゆるコンポーネントに共通な内部インターフェースが存在し、 更にはコンポーネントはいくつかの種類のコンポーネントを継承したいです。 不可能なコードで記すと、このようなことがしたいです。 【拡張TextBox】 public class ExTextBox : AbstractTextBox { } 【抽象TextBox】 public abstract class AbstractTextBox : TextBox, ICommonControl {  public AbstractTextBox() {   _ifMethod();  }  private void _ifMethod() {  ←これ   // 処理  } } 【内部インターフェース】 public interface ICommonControl {  void _ifMethod(); } インターフェースはpublic宣言以外定義が行えず、内部で利用される インターフェースとしては使えません。 別にインターフェースをそのまま実装すれば出来なくはないですが、 外部にインターフェースを実装したメソッドが見えるのはマズいです。 もしくは多重継承的なことが出来れば解決すると思うのですが・・・。 コンポーネントを継承する関係で、直前のクラスはTextBoxやLabelなどと いったクラスを継承するしかない為、それ以外の内部部分を共通化 したい場合に、どうすればいいのか分かりません。 実現させる方法が思いつかない為、何かシンプルな一例をご提示 頂けないでしょうか?

  • 【C++】相互参照

    以下のような相互参照は、 感覚的には、なるべくならしない方が良いと感じるのですが、 どのようなメリット・デメリットがあるでしょうか? class A B* m_b class B A* m_a ■少なくとも、多くのクラスによって構成された巨大なDLLが、  相互参照ばかりで作られると、  (1)クラスAのポインタ型のメンバーが、クラスB内で値が変わりうる、   また、クラスBを、クラスCで参照していたら、そこでも値が変わりうる。   さらにクラスCを、クラスDで参照していたら、(略)となり、   処理・メンバー値の変更の影響の把握が困難になる。  (2)lib/objの作成順のミスや管理、  (3)いずれかのクラスのリコンパイルが発生した時、   リリース物のリコンパイルが発生しまくる。  ということがあり、良くないと考えています。 - - - - - - - - - - - - - - - 相互にインタフェースし合う項目を、メンバーとして宣言しつつ、 そのGetter、Setterを用意すれば、強結合にせずに作れるという認識ですが合っていますか? class A B* m_b int x1、y1、z1   x1、y1、z1のGetter、Setter class B Privateなメンバーx、y、z int x2、y2、z2   x2、y2、z2のGetter、Setter .

  • 参照カウンタについてその3

    参照カウントについて質問で ”単純な実装"では、共有オブジェクトの廃棄は最後に参照解除したスレッドで行われます。一斉に解放される場合、最後に参照されたスレッドが重くなります。とは、なぜ最後に参照されるとスレッドが重くなるのでしょうか? また、"単純な実装"では、カウンタが0になったら、"自分で自分を"削除します。 この”自分で自分を"というところがポイントです。 何か、使われている変数を監視しているスレッドが存在して、 それが、カウントの値をチェックし、0であったら削除する (これがGCですね) とは違います。 とは何が違うのでしょうか?もしかして"単純な実装"は自分で自分を破棄してGCでは別の関数か何かで削除しているということでしょうか あとそれぞれのスレッドが固有のオブジェクトを持っている場合、 "単純な実装"では スレッドごとにオブジェクトの破壊コードが実行されることになります。これは破棄されるときのことをいっているのでしょうか?

  • C#のインスタンスを参照渡ししたい

    メインのクラスAにウェブブラウザAがあります。 クラス A { メソッドA(){  ウェブブラウザA.Navigate(URL); } メソッドC(){  MessageBox.Show("これは成功"); } } クラス B {  メソッドB(ウェブブラウザA){   ウェブブラウザA.Navigate(URL);//成功  } A a = new A(); a.メソッドA();//失敗 a.メソッドC();//成功 } このようなプログラムを作っています。 クラスBをインスタンスして実行すると クラスBのメソッドBは成功しますが、クラスAの方で宣言しているa.メソッドAは失敗します しかし、a.メソッドC();は成功します。 これは、a.メソッドAは、その上のA a = new A();でつくられた新しいインスタンスのなかで処理がされていて起動時につくられたクラスAのインスタンスとは別のものになっているからだと思うのですが、まちがいないでしょうか? この処理を成功させたい場合、起動時に作られたクラスAのインスタンスをメソッドBの引数に参照渡しですれば、  メソッドB(ウェブブラウザA){   ウェブブラウザA.Navigate(URL);//成功   メソッドA();  } も可能なのではないかと考えているのですが、可能でしょうか?またそのインスタンスを引数にする方法はどのようなものでしょうか? ちなみに、クラスBはDLLに置いてあり、メソッドAは複数のDLLで使うので毎度書くのは面倒なのでクラスAの中で呼び出して使いたいと考えています。

  • C#とC++/CLI間でポインタが指す内容が変わる

    現在、C++/CLIプログラムをC#で使う必要があり、 C++/CLIで定義したメソッドとクラスでC#側とやり取りする必要が生じております。 以下の書き方で、C++/CLIとC#間のクラスのやり取りはできたのですが、 C++/CLI側で定義されているメソッド内で、ポインタが指し示す値(*id.head)が変わってしまいます(文字化けみたいな感じになる)。 引き渡したポインタ変数の値は一致しているのですが、 どうすれば、C++/CLI側で値を正しく取得できるのでしょうか?。 【C++/CLI側で定義されているクラス】 public value class class1 { public : ULONG code; header    *head; }; typedef struct _header { CHAR achCHdrType[2]; CHAR achMsgLen[2]; } header ; 【C++/CLI側で定義されているメソッド】 ULONG session::open(class1& id) { return session_oepn(id.code, *id.head) } 【C#側でのメソッド参照】 class1 c1 = new class1(); uint status = session.open(&c1); よろしくお願いします。

  • 継承、実装についてまとめています。この図は正しいですか?

    継承、実装についてまとめています。この図は正しいですか? クラス1 から継承した クラス2のものを、クラス3で継承するのでしょうか? クラス1 │ int a; │ static int b; │ │ クラス1() { } │ │ int methodA () { } │ static int methodB() { } ↓ サブクラス1 extends クラス1 │ int a; // 継承 │ int c; │ static int d; │ │ サブクラス1() { } // コンストラクタは継承しない、super()で呼び出す │ │ int methodA () { } // 継承 │ int methodC() { } │ static int methodD() { } ↓ サブクラス2 extends サブクラス1 implements サブインタフェース1, サブインタフェース2… ↑ int a; // サブクラス1のフィールドを継承 │ int c; // 継承 │ int e; │ static int f; │ public static final int g; // 実装(サブインタフェース1) │ public static final int h; // 実装 │ │ サブクラス2() { } │ │ int methodA () { } // サブクラス1のメソッドを継承 │ int methodC() { } // 継承 │ int methodE() { } │ static int methodF() { } │ int methodG() { } // 実装(サブインタフェース1) │ int methodH() { } // 実装 │ interface サブインタフェース1 extends スーパインタフェース1... ↑ public static final int h; │ │ public abstract int methodE() { } // 継承 │ public abstract int methodH() { } │ interface スーパーインタフェース public static final int g; public abstract int methodG() { }

    • ベストアンサー
    • Java

専門家に質問してみよう