添字演算子

このQ&Aのポイント
  • #include <iostream>\n\nclass hoge{\n\tprivate:\n\t\tint a;\n\tpublic:\n\t\thoge(){\n\t\t\ta = 0;\n\t\t}\n\n\t\tint operator+(int fuga){\n\t\t\ta = a + fuga;\n\t\t\treturn a;\n\t\t}\n\n\t\tint operator[](int fuga){\n\t\t\treturn 1;\n\t\t}\n};\n\nint main(){\n\thoge* p;\n\tp = new hoge;\n\tstd::cout << ((*p) + 5) << std::endl;\n\tstd::cout << ((*p)[1] ) << std::endl;\n\t\n\t// 5\n\t// 1\n\n\t// std::cout << ((*p) [] 1); エラーです。何故ですか?\n}
  • C++の添字演算子について質問です。\n\nこのコードでは、hogeクラス内に+演算子と、[]演算子のオーバーロードが定義されています。+演算子はaにfugaを足し合わせた結果を返し、[]演算子は常に1を返します。\n\nmain関数では、hogeクラスのインスタンスを作成し、そのインスタンスの+演算子と[]演算子を利用して値を取得しています。+演算子には引数として5を渡しており、[]演算子には引数として1を渡しています。\n\nその後、取得した値を出力しています。出力結果は「5」「1」となります。\n\nしかし、最後のコメントアウトされた行、「std::cout << ((*p) [] 1);」がエラーになってしまいます。何故エラーが発生するのでしょうか?
  • この質問では、C++の添字演算子について説明します。\n\nコードでは、hogeクラスに+演算子と[]演算子のオーバーロードが定義されています。+演算子はaにfugaを足し合わせた結果を返し、[]演算子は常に1を返します。\n\nmain関数では、hogeクラスのインスタンスpを作成し、そのインスタンスの+演算子で5を足し合わせて値を取得し、[]演算子で1を取得しています。\n\nしかし、最後の行、「std::cout << ((*p) [] 1);」はエラーになります。これは、[]演算子の使用方法が誤っているためです。[]演算子はインデックスを指定して要素にアクセスするための演算子ですが、[]の後に値を指定する必要があります。値を指定しないとエラーが発生します。\n\n以上が、なぜエラーが発生するのかの説明です。
回答を見る
  • ベストアンサー

添字演算子

#include <iostream> class hoge{ private: int a; public: hoge(){ a = 0; } int operator+(int fuga){ a = a + fuga; return a; } int operator[](int fuga){ return 1; } }; int main(){ hoge* p; p = new hoge; std::cout << ((*p) + 5) << std::endl; std::cout << ((*p)[1] ) << std::endl; // 5 // 1 // std::cout << ((*p) [] 1); エラーです。何故ですか? }

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

>// std::cout << ((*p) [] 1); エラーです。何故ですか? 定義された構文に従ってないから。 関数的に呼び出したいのなら (*p).operator[](1) とか。

himajin100000
質問者

お礼

みたいね。 どうやら int operator +(int fuga){ return 1; } という定義が使えるようなので int operator mod(int fuga){ return 1; } とか書いたら エラー E2076 hoge.cpp 15: オーバーロード可能な演算子が必要 って言われたから

himajin100000
質問者

補足

あれ?独自の演算子を定義できる方法だと思ったけど, int operator$(int fuga){ a = a + fuga; return a; } とかやったら コンパイルエラーだ(汗 #もしかして規格側で定義された演算子をオーバーロードできるだけで 独自の演算子を書いたり出来ない?(汗 #そうであれば、「規格でそうなっている」で納得することにするけど。 ##っつーのも ## $$演算子とかを俺が定義した場合 ## $1$と $$ 1 のどちらの演算子を定義したことになるのかなーと思ったから。 ## もし記述方法によって書き換えられるとしたら,C++の元になっている ## Cはどういう構造の違いを与えているのかなーと。

関連するQ&A

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

    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; }

  • 変数の隠蔽とスコープ

    いつまでも初心者のままじゃ駄目だなあと思い, 用事のついでに本屋まで行って 評価が高いらしい http://www.amazon.co.jp/exec/obidos/ASIN/4797328541/Lvdrfree-22?dev-t=D1KDF7Q74DD3A2%26camp=2025%26link_code=xm2 を100ページほど立ち読みしてみた。(買ってません) で、まあ内容を理解できているかは別として 可視性とアクセス制御という話があって Java や C#の時の知識から 以下のコードの出力結果は一応理解できます。 折角なので 質問もコードの中に書いてみました。 ========================== #include <iostream> int a = 5; class fuga{ public: int a; fuga(){ a = 3; } }; class hoge : fuga{ //実際の書籍では public fugaだったような public: void printa(){ std::cout << a << std::endl; //コンパイル通っちゃったけど,ここからグローバル変数a(==5)にアクセスする方法はあるの? } }; int main(){ hoge* p = new hoge; p->printa(); std::cout << a << std::endl; delete p; // 3 // 5 }

  • 仮想関数と継承について

    #include <iostream> using namespace std; class AAA { public: virtual aaa() { cout <<"aaa(void)"<<endl;} }; class BBB : public AAA { public: virtual aaa(int a) { cout <<"aaa(int)"<<a<<endl;} }; int main() { BBB bbb; bbb.aaa();<--これがエラーになります。 return 0; } どうして、既定クラスの引数なしのaaa()はよぶことが できないのでしょうか?

  • オーバーライドされた演算子の継承

    オーバーライドされた演算子は継承されますか? 今やろうとしていることは、変換演算子を継承しようとしています。 試してみたところ警告もなく出来ましたが、この動作は規格上正しいのでしょうか? #include <iostream> class base { public: operator bool() { return true; } }; class derived : public base { }; int main() { derived d; if(d) { std::cout << "true"; } }

  • 【C++】アドレス演算子について質問です。

    アドレス演算子について質問です。 下記のように"&"を関数名の前に付けた場合下記のように出力されます。 &グローバルメソッド:002E1226 &クラス::メンバメソッド:1 1行目はグローバルメソッドなので実態が存在するのでメソッドのアドレスが表示されている。 2行目は実態が存在しないと思うのですが、あってますでしょうか? また、何故1が表示されてしまうのでしょうか? -------------------------------------------------------- #include "stdafx.h" #include <iostream> using namespace std; class Class1{ public: void f(){ return; } }; void Func1(){ return; } int main() { cout << "&グローバルメソッド:" << &Func1 <<endl; cout << "&クラス::メンバメソッド:"<< &Class1::f <<endl; getchar(); return 0; }

  • (C++)スマートポインタをメンバ変数で使いたい

    Viual Studio 2013を使ってC++のコードを書いています。 以下のコードで、new-deleteの クラス生成をスマートポインタで置き換えたいのですが、 うまくいきません。具体的には/* not smart */の部分を スマートポインタで置き換えたいが、C2059のエラーが出てきて コンパイルできないのが理解できていません。 どなたかわかる方教えていただければ幸いです。 よろしくお願いします。 // ----コードは以下---- #include <memory> #include <iostream> class Hoge { public: Hoge(){ std::cout << "constructed!" << std::endl; }; ~Hoge(){ std::cout << "destructed!" << std::endl; }; private: }; class Hogehoge { public: Hogehoge(){}; ~Hogehoge(){ delete test; /* not smart */}; private: // error C2059 w/ VS2013 // std::unique_ptr<Hoge> test(new Hoge); Hoge* test = new Hoge; /* not smart */ }; void main() { Hogehoge foo; }

  • C++の話です。

    C++の話です。 静的メンバ変数としてクラスを宣言した場合、デストラクタが呼ばれていないようなのですが、呼ぶ方法はありませんか? できれば「new」「delete」を使わずできると理想的です。 分かる方教えていただけると助かります。 以下、サンプルコードです。 「デストラクタが呼ばれました」と出力されない上、デバッガを使って試してみましたが、やはり呼ばれていないようです。 #include<iostream> class Test{   public:     ~Test(){       std::cout<<"デストラクタが呼ばれました"<<std::endl;     } }; class A{   private:     static Test T; }; int main(){   A a;   return 0; }

  • C++のクラスについて

    /*以下のコメントがある行では何故、コンストラクタ(class2::class2)を指定出来ないのですか? デストラクタ(class2::~class2)の場合も問題なくコンパイルが通り、実行できます (http://codepad.org/1oJkxjyZ の23行目) 開発環境 Windows XP SP3 コンパイラ:GCC 実行結果 class1のコンストラクタ class2のコンストラクタ aiueoの実行 class2のデストラクタ class1のデストラクタ */ #include<iostream> class class1; class class2; class class1{ public: class1(); ~class1(); private: class2*pointer; }; class class2{ public: class2(); ~class2(); void aiueo(); }; class1::class1(){ std::cout<<"class1のコンストラクタ"<<std::endl; pointer=new class2(); pointer->aiueo(); //aiueoを~class2に置き換えてもコンパイル出来るが、class2だとエラーが出る } class1::~class1(){ delete pointer; std::cout<<"class1のデストラクタ"<<std::endl; } class2::class2(){ std::cout<<"class2のコンストラクタ"<<std::endl; } class2::~class2(){ std::cout<<"class2のデストラクタ"<<std::endl; } void class2::aiueo(){ std::cout<<"aiueoの実行"<<std::endl; } int main(){ class1 test1; return 0; }

  • 二項演算子のオーバーライドについて

    目黒@C++学習中 です。 二項演算子のオーバーライドする時 どうして"friend"にしないといけないの? 以下テスト ソース #include <windows.h> #pragma warning(push,3) #include <iostream> #include <iomanip> #pragma warning(pop) using namespace std; class clsTest { private: double m_dNum; public: clsTest() : m_dNum(0) {} clsTest(double dNum) : m_dNum(dNum) {} ~clsTest(){}; friend clsTest operator + (const clsTest oP1,const clsTest oP2) { return clsTest(oP1.m_dNum+oP2.m_dNum); } friend ostream& operator << ( ostream& oOutStream,const clsTest oT ) { return oOutStream << "T(" << oT.m_dNum <<")"; } }; void main() { clsTest oT1(2); clsTest oT2(5); clsTest oT3 = oT1 + oT2; cout << setiosflags(ios::fixed) << setprecision(4); cout << oT1 << endl; cout << oT2 << endl; cout << oT3 << endl; }

  • shared_ptr クラスについて

    shared_ptrクラスを使いたいのですが、使えません、どうしてでしょうか?ソースはこれです。 #include<iostream> #include <string> #include <fstream> #include<memory> using namespace std; class SMonster{ string name; int power; public: SMonster(); SMonster(int p); ~SMonster(){ }; void SetPower(int p); int GetPower(SMonster& t)const; void walk(const string& str); int GetPoint(void)const; }; class B {}; class D : public B {}; int main(void) { shared_ptr<D> sp0(new D); SMonster m(200); SMonster n(100); std::cout<<m.GetPower(m)<<std::endl; std::cout<<n.GetPower(n)<<std::endl; ShowWindow(10); }

専門家に質問してみよう