• 締切済み

アドレスの代入禁止方法

宜しくお願いします。 私が考えている設計の、あるオブジェクトは生成されるインスタンスがプロジェクト内で単一であるとするものなので、アドレスの代入を禁止にしたいのです。 この場合はアドレスの代入禁止を目的としているので、メモリリークが発生していますがスマートポインタ等のメモリ管理法は使用しません。 operator=にてアドレスの代入禁止、もしくは別の方法がありましたら教えて頂けませんでしょうか。 以下はネット等を参考にしたソースコードです。 #include <crtdbg.h> class CHoge { public: CHoge(){}; private: CHoge(const CHoge&){}; CHoge& operator=(const CHoge&); }; int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // 具体的にはこのような場合を想定した時の為です CHoge *pHoge = new CHoge; CHoge hogeB; pHoge = &hogeB;//ここを禁止する方法がわかりません return 0; }

みんなの回答

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

> pHoge = &hogeB;//ここを禁止する方法がわかりません 一番手っ取り早い方法は、 class CHoge {  ... private:  CHoge* operator&() const; }; とすることだと思います。 ただし、この場合でも、 pHoge = reinterpret_cast<CHoge*>(&reinterpret_cast<char&>(hogeB)); とされるとアドレスが取れてしまいます。 もっとも、ここまでやるのは明らかに悪意がありますから、開発メンバーの人間性を問うた方がよいでしょう。 一応質問への回答としては上記の通りですが、できればきちんとSingletonパターンを使った方がよいとは思います。

--owata--
質問者

お礼

ご回答ありがとうございます。大変参考になりました! &そのものをprivateにするという発想は浮かびませんでした。。。 reinterpret_castはこういった用法があることも含め、まだまだ勉強や発想力が足りていないと実感します。 設計に関しては皆さんが仰ってるようにやはりSingletonパターンが典型的であって、見た人もわかりやすいのではないだろうかと思います。 また一つプログラミングテクニックを身に付けることが出来ました。 これからも精進していきます。 大変ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • koko_u
  • ベストアンサー率12% (14/116)
回答No.1

>生成されるインスタンスがプロジェクト内で単一であるとするものなので、アドレスの代入を禁止にしたい この前後の繋がりがわかりません。 インスタンスがプロジェクト内で単一であることが保証できれば、それを指し示すポインタ変数は複数あっても通常問題ないのでは? 典型的な Singleton パターンでは駄目な理由がわかりません。 >CHoge *pHoge = new CHoge; >CHoge hogeB; ここで既にヒープ領域とスタック領域に「2つ」CHoge インスタンスが生成されているのですが。。。

--owata--
質問者

補足

ご回答ありがとうございます。 申し訳ありません。単一オブジェクト云々は後で読み返しまして、当初に考えていた文章が混じっていたようです。 ですので単一オブジェクトにしなければならないという前提と設計は関係が無いということでお願いします。 この際、operator=での方法だけでも構いません。 ご教授お願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C++のクラスの可変引数化を禁止する方法。

    C++のクラスの可変引数化を禁止する方法。 クラスのインスタンスをprintfの引数にするのをコンパイル・エラーにする方法はないでしょうか? コピーコンストラクタや代入のオーバーロードをprivateにしてもエラーが出ないので方法を探しています。 #include "stdafx.h" class CTest { private: int intdata; public: CTest() : intdata(0) { }; private: void operator =(const CTest& src) {} CTest(const CTest& src) {} }; int _tmain(int argc, _TCHAR* argv[]) { CTest ctest; printf( "%s %p\n", ctest, ctest ); return 0; }

  • キャストによるアドレス変更について

    多重継承クラスのインスタンスのポインタを基底クラスのポインタ に代入するとき、キャストで、vtableへのポインタを変更するために、 多重継承クラスのインスタンスのポインタのアドレスから4byte加算 したアドレスが、基底クラスのポインタに代入されます。 以下のプログラムは、多重継承ではないですが、pCのポインタの アドレスに4byte加算してpAに代入されます。pAのデストラク タはvirtual宣言していないので、pAが指すアドレスにはvtable のポインタはないはずですが、4byte加算するという動作が起こるのは 何故でしょうか。 #include <iostream.h> class AAA { public: AAA(){} ~AAA(){} }; class BBB:public AAA { public: BBB(){} virtual ~BBB(){} }; class CCC:public BBB { public: CCC(){} ~CCC(){} }; int main(void) { CCC *pC = new CCC(); AAA *pA = (AAA *)(pC); delete pA; return 0; }

  • operator代入演算子のやり方で疑問が

    C++の勉強をしています。 そこでoperatorを使うことをやっているんですが、この演算子、引数を二つつけるとエラーになります。クラス内で定義するとこうなります。 ですがグローバルで定義するとエラーが出力されません。 何故なんでしょうか? 戻り値の関係でしょうか?  class Complex { public: Complex() { } public: // これはエラー、この演算子関数のパラメータが多すぎますと出力される const Complex operator+(const Complex x, const Complex y) { } }; // これはでない・・・ const Complex operator+(const Complex x, const Complex y) { } 上記のプログラムだと、下に書いてある代入演算子は問題ありません。 なぜこうなるんでしょうか? ご教授お願いします。

  • ポインタの代入の省略について

    下記のプログラムにおいて、 Base* const sensor(mSensors[0]);は Base* const sensor = mSensors[0]; と同意だということなのですが、 C++のこのようなポインタの代入の記述法(?)について 書かれた参考書をもっておらず、最初かなりとまどいました。 このような記述法に名前(XX法)はついているのでしょうか? またこのような表記法について説明がなされている参考書または Webページがあればご教示いただけないでしょうか? よろしくお願いします。 #include <stdio.h> class Base { protected: public: Base(int n); void func(); }; Base::Base(int n) { printf("hello, world\n"); } void Base::func() { printf("func is called\n"); } int main(void) { Base* mSensors[2]; mSensors[0] = new Base(5);       Base* const sensor(mSensors[0]); sensor->func(); return 0; }

  • 警告「代入される前に使われている」を出す方法

    bccで以下のコードをコンパイルすると。 「'i' は、おそらく値が代入される前に使われている」 と警告が出ますが、 「'h' は、おそらく値が代入される前に使われている」 とは警告を出してくれません。 警告を出す方法ってないでしょうか? Hogeメンバに bool 型の初期化フラグでも実装しようかな・・・。 #include <iostream> class Hoge { public: Hoge(){ } Hoge( int i ){ t = i; } operator int(){ return t; } int t; }; int main() { int i; Hoge h; std::cout << i << std::endl; std::cout << h << std::endl; return 0; }

  • global operatorについて

    特定のクラスのポインタの比較(less)をオーバーライドしたいのですが、 1. そのような処理は実装可能か? 2. 実装可能とした場合、operatorの宣言は どのように書いたらよいのか? 具体的には以下のようなコードになります。 ---- class Test { public: float m_Priority; Test(const float p) { m_Priority = p; } }; Test* a = new Test(0); Test* b = new Test(1); if(a < b){ a = a; } ---- 試しに bool operator < (const Test* const l, const Test* const r) { return l->m_Priority < r->m_Priority; } と書いてみましたが、コンパイルエラーが出てしまいました。 補足 ・ポインタのオーバーライドが非常に危険なこと ・組み込み方のオーバーライドが禁止されている 上記の2点は確認済みです。 ポインタを格納するクラスを別途作成し、 その中で比較をすればよいのでしょうが、 高速化のためにどうしてもポインタ比較の オーバーライドが必要になりました。

  • C++言語 メンバ関数

    何気なく使用しているクラスのメンバ関数、これの中身が実際どうなってるか知りたいです。大別して2種類に分かれますので以下の2つを 教えて下さい。また詳しく載っているサイトなどあれば教えて下さい。 1,stringクラスMid(int start,int length関数と operator関数+について class String{ char *p; char *q; public: //各定義 }; String String::Mid(int start,int length) const { // } String String::operator+(const String&s)const{ return String(p+s.q+s.p); } 最初の方はイメージもつかず、2つめのほうはポインタに ポインタを加えようとしましたとでます。 教えて下さい。

  • クラスの作成について

    すみません、クラスの作成について少し教えてください。 以下のようなクラスがあります。 class Vector { public:   //※他、ここにいくつかのメンバ関数がある。   // 入出力   friend istream& operator>>(istream& is, Vector& vector);   friend ostream& operator<<(ostream& os, const Vector& vector); private:   double x;   double y; }; ・・・この// 入出力の istream operator, ostream の具体的な書き方がわかりません。 よかったら教えてください。

  • オペレータ定義について

    すみません、オペレータ定義について教えてください。 ■以下のようなクラスに、[] が定義されていて、 class String { public:       ・       ・ (メンバ関数がいくつかあり)       ・       // num 番目の文字を返す       char operator[](int num) const;       char& operator[](int num); private:       char* string; }; ■関数はこのように書かれていて、 char String::operator[](int num) const {     // 文字列の num 番目の文字を返す 1     return string[num]; } char& String::operator[](int num) {      // 文字列の num 番目の文字を返す 2      return string[num]; } ■これを →[] main() から使うにはどのようにしたらいいのでしょうか?

  • DirectXのD3DXVECTOR3

    directxでのCDに書いてあるこのソースの一部の事で質問します。 D3DXVECTOR3 mVecDir; mVecDir = D3DXVECTOR3( -0.5f, -0.5f, 1.0f); --------------------------------------------------------------- D3DXVECTOR3をDirectX SDK October 2004で調べたのですが、 typedef struct D3DXVECTOR3 : public D3DVECTOR { public: D3DXVECTOR3() {}; D3DXVECTOR3( CONST FLOAT * ); D3DXVECTOR3( CONST D3DVECTOR& ); D3DXVECTOR3( CONST D3DXFLOAT16 * ); D3DXVECTOR3( FLOAT x, FLOAT y, FLOAT z ); // 型変換 operator FLOAT* (); operator CONST FLOAT* () const; // 代入演算子 D3DXVECTOR3& operator += ( CONST D3DXVECTOR3& ); D3DXVECTOR3& operator -= ( CONST D3DXVECTOR3& ); D3DXVECTOR3& operator *= ( FLOAT ); D3DXVECTOR3& operator /= ( FLOAT ); // 単項演算子 D3DXVECTOR3 operator + () const; D3DXVECTOR3 operator - () const; // 2 項演算子 D3DXVECTOR3 operator + ( CONST D3DXVECTOR3& ) const; D3DXVECTOR3 operator - ( CONST D3DXVECTOR3& ) const; D3DXVECTOR3 operator * ( FLOAT ) const; D3DXVECTOR3 operator / ( FLOAT ) const; friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3& ); BOOL operator == ( CONST D3DXVECTOR3& ) const; BOOL operator != ( CONST D3DXVECTOR3& ) const; } D3DXVECTOR3, *LPD3DXVECTOR3; これを自分が見た限り、戻り値がないと思います。 何故、mVecDir = D3DXVECTOR3( -0.5f, -0.5f, 1.0f);のD3DXVECTOR3は戻り値があるのでしょうか? ちなみに、質問のソース2行はD3DXVECTOR3 mVecDir( -0.5f, -0.5f, 1.0f);でもOKですよね? よろしくお願いします。

このQ&Aのポイント
  • 皮膚用の抗炎症剤のチューブのキャップが割れてきた時、代替品を探す際に製薬会社でキャップのみを売っているかどうか気になります。
  • 皮膚用抗炎症剤のチューブのキャップが壊れた場合、製薬会社でキャップのみを販売しているか探したいです。
  • 皮膚用抗炎症剤のチューブのキャップが破損した時、製薬会社でキャップの単品販売は行われているか知りたいです。
回答を見る