• ベストアンサー

クラスのインスタンスって何者?

麻野 なぎ(@AsanoNagi)の回答

回答No.3

「ソースBの一番外側」という表現ですが、こ れは具体的にどこでしょうか? 「内容が消えた」ということですから、本当に は、「一番外側」に書かれてはいなかったとい うことになります。 例えば、「同じファイル」の中で、 class BClass; void funcB() { BClass Bmenber; ..... } main() { for (i = 0; i < 100; i++) { funcB(); } } と書かれてたなら、funcB() が呼び出される たびに、Bmember は、「作り直されます」 これは auto 変数(自動変数)と同じ挙動で、 気持ちとしては、書かれた場所を通過するた びに中身が新しくなります。 これを避けるためには、 void funcB() { static BClass Bmenber; ..... } とします。 これが、static 変数(静的変数)の挙動と なり、プログラムの実行に「先だって」一度 だけ生成されます(必要により初期化も) さて、「一番外側」とは、 class BClass; BClass Bmenber; void funcB() { ..... } main() { for (i = 0; i < 100; i++) { funcB(); } } と、どの関数にも属さない形で記述するもので、 これが、グローバル変数となります。 グローバル変数も、プログラムの実行に「先 だって」一度だけ生成・初期化されます。 ですから、この位置にあれば、static がなく ても、プログラムの実行中に、再度生成される ことはありません。 さて、最後に、グローバル変数の位置(関数 の外)で、static を付けると、これは、「静 的変数」とは別の意味を持ちます。 グローバル変数は、 BClass Bmenber; だけであれば、他のファイルで、 extern BClass Bmember; と宣言することで、アクセス可能となります。 これに対して、 staic BClass Bmenber; と指定したもの(関数の外側で)は、その他の ファイルからは、一切アクセスできなくなります。 この点で、 ・関数の中で static 宣言したもの ・関数の外で static 宣言したもの は、static の意味が異なるのが、C++の 変則的なところです。 グローバル変数が「怖い」のは、変数の値が おかしくなったときに、どこで(もしくは、 どのファイルで)その、おかしな値をセット しているか容易にわからないところです。 この「怖さ」を軽減するために、ひとつのファ イルの中だけで(しかし、複数の関数から) 参照する必要のあるものは、関数の外側で、 static を付けて宣言します。 こうすれば、「少なくとも、そのファイルの中の 関数しか変数をいじっていない」とわかるから です。

noname#202167
質問者

お礼

おおおおお・・・ありがとうございます・・! >「内容が消えた」ということですから、本当に >は、「一番外側」に書かれてはいなかったとい >うことになります。 なるほど、つまり毎回内容が消えてしまっていたのは 恐らく私がそこを間違えて関数の内側に書いてしまっていたからで、 普通は外側に書いていれば消える事は無いのですね、 今までずっとつっかえていた物が取れました・・! 本当にありがとうございます・・! >・関数の中で static 宣言したもの >・関数の外で static 宣言したもの > >は、static の意味が異なるのが、C++の >変則的なところです。 私が疑問を抱えていたもう1つはコレだったのですね。 staticについては勉強しなおそうと思います。 >グローバル変数の怖さ なるほど・・プログラムが肥大化すると たったそれ1つで膨大な手間と労力を取られるのですね。 数が少ない内は意識してられますが増えると極めて危険なのでしょうね・・。 なるべくグローバル変数を使わない設計をできるよう 色々と勉強して行こうと思います。 前回のご助言から、本当に色々ありがとうございました。 長い間恐々使っていたコードの疑問に こんなに丁寧なお答えを頂けるとは思ってすらいませんでした。 何度も読み返してしっかり頭に叩き込もうと思います。ます。 本当にありがとうございました・・!

関連するQ&A

  • 同一クラスインスタンス名で別クラスのインスタンス作成方法(C++)

    下記ソース(Java)の処理をするような、C++の実装方法を教えていただきたいです。 【処理内容】 クラスBのインスタンスを保持しており、クラスBのインスタンス名と同一であるクラスAのインスタンス生成 ClassA A_Instance = (ClassA)Class.forName(B_instance.name).newInstance(); 要はクラスインスタンスの名前の求め方がわからないのです。それさえわかれば、newしてクラスポインタを返すメソッドを用意すれば何とかなると考えていますが。 ※C++のAPI一覧はどこにあるのだろうか・・・

  • 宣言と定義 通用範囲やインスタンス

    C++ビギナーの者です。 オブジェクト指向プログラムを見よう見まねでやって壁にぶつかっています。 わからない事が3つ程あります。 1. 「ヘッダーファイル中」と「ソースファイルの、関数・クラスの外側」と「その中」 この3箇所での、宣言や定義にはどんな制限等が存在するのでしょうか? ヘッダーに書くとダメなものが、ソースでならOKだったり混乱しています。 2. ClassAというクラスのインスタンスを、「複数の関数」で使いたい場合に  「ソースファイルの、関数・クラスの外側」 で ClassA classa; 等として、ソース内の複数の関数で利用するのは大間違いなのでしょうか? グローバル変数が何度も初期化されるトラブル等が起きています。 3. ソースファイルA側でデータを入れたvectorを ソースファイルB側で使うにはexternを付けるだけで良いのでしょうか? 手元にある参考資料から、見よう見まねでやってしまってるのですが、 C++の解説サイトにはあまり、こういった情報が載ってないのか見つけられません。 やはり書籍を買って勉強すべきだと痛感し始めたのですが、 解説のあるWebサイト、おすすめの書籍などが有りましたら それらも教えて頂けると幸いです。 よろしくお願いします っ_ _)っ

  • cocoa、objective-cのクラスをインスタンス化する順番を変えたいのですが可能なのでしょうか?

    cocoa、objective-cなのですが NSTableViewのデータを用意するにあったて データを用意するクラス”A”がIBによってインスタンス化の設定がなされていて クラス”A”が用意するデータがクラス”B”を参照する仕様なのですが、 クラス”B”もIBによってインスタンス化の設定がなされていてIBOutletによって ”A”と”B”お互いに接続されているのですが、クラス”A”がデータを参照するときに まだインスタンス化もしくは接続がなされていないようなので インスタンス化する順番を変えたいのですが可能なのでしょうか? それとも何か他の原因なのでしょうか? ご存知の方教えていただけないでしょうか? よろしくお願いします。

  • 別のクラスのインスタンスの作り方

    現在、javaからrubyに移行するために勉強しているのですが、別のファイルに定義したクラスのインスタンスが作成できなくて、困っています。 具体例をあげると require './B' class A end def initialize b = new B end end --別のファイル class B def initialize p 'hello' end  public : initalize end こんな2つのファイルがあったとして、Aのインスタンスを作成すると、 undefined method `B’ というエラーがでます。 私としてはこのエラーの原因がinitializeがデフォルトでprivate宣言なのが原因だと考えているのですが、publicと指定してもエラーとなることから、いくつか疑問が湧いたので質問させていただきます。 1、そもそもBクラスのインスタンスが作成できないのはinitializeがデフォルトでprivate宣言なのが原因なのか? 2、1があっていたと仮定するとBクラスのinitializeをpublic指定しているのになぜ呼び出せないのか? 3、rubyはなぜデフォルトでinitializeがprivateなのか?(javaではコンストラクタをprivateにするということは普通はしない。使うときはシングルトンやUtilのようなクラスを作るときに限る) 以上です。よろしくお願いします。

    • ベストアンサー
    • Ruby
  • rubyのインスタンスのクラス名取得

    現在rubyを勉強しているのですが、わからないことがありこまっています。 それはインスタンスにどんなクラスが入っているかわからないのです。 具体的にソースで説明させていただきます。 f= File.open("hello.txt") このfのインスタンスにどんなクラスのインスタンスが格納されているか知りたいのですが、何か方法は無いのでしょうか?

    • ベストアンサー
    • Ruby
  • クラスとインスタンスについて

    入社1年目のプログラミング経験0のSEです! Javaのクラスとインスタンスについてぜんぜん理解できません! 下のソースをどうしたらいいのかわからないです。 import java.io.*; class SumAndAvgMain{ public static void main(String argv[]){ BufferedReader r = new BufferedReader(new InputStreamReader(System.in),1); try{ //3教科の得点を入力しintに変換 //SumAndAvgクラスのインスタンスを作成 //合計点及び平均点を出力する。 }catch(IOException e){ System.out.println("例外発生"+e); } } } class SunAudAvg{ public static void main(String args[]){ //各教科の得点用のフィールド int kokugo; int suugaku; int eigo; //SumAndAvgクラスのコンストラクタ SumAndAvg(int kokugo,int suugaku,int eigo){ //フィールドに国語の点数を代入 //フィールドに数学の点数を代入 //フィールドに英語の点数を代入 } //3教科の合計点を求める int getGoukei(){ } //3教科の平均点を求める double getHeikin(){ } }

  • マルチスレッド下でのインスタンス変数・クラス変数

    よろしくお願いします。  マルチスレッド下で動作するクラスを作成しています。データにアクセスするためのオブジェクトを クラスのフィールド値として保持し、使い回しを行いたいと考えています。このデータアクセスオブジェクト(以下Dao)内では特にフィールドは使用せず、全てローカル変数のみで動作するようになっています。Dao自体は初回のクラス生成時にstatic処理にてフィールドにセットされます。  このDaoを保持するフィールドは、staticなクラス変数が良いのか、インスタンス変数として保持する方が良いのか迷っております。  クラス変数ならばPermanent領域をオブジェクト1つ分のメモリ使用で済み、インスタンス変数だとスレッド毎にheapを使い、処理数が増えるとメモリ圧迫しちゃう?と安易に考えてしまったりしています。  ご意見・ご助言よろしくお願い致します。

    • ベストアンサー
    • Java
  • Oracleインスタンスへの接続制限について

    1台のサーバにOracleのインスタンス(A、B)を複数立てた環境において、 クライアント1からはAインスタンスのみ利用可能、クライアント2からは Bインスタンスのみ利用可能とさせる事は可能でしょうか? (クライアント2の利用者にAインスタンスのインスタンス名、  ユーザ名、パスワードが漏れてしまっても、Aインスタンスに  接続できないように制限できればと思っています。) 宜しくお願いします。

  • 子クラスのインスタンスから親クラスのインスタンス変数の内容を表示する親クラスのメソッドを叩きたい

    お世話になっております。 rubyのコーディングで疑問が発生しましたので、質問させてください。 以下の様にクラスを定義してあるとします クラスA 体裁を整えて標準出力するクラス  ・インスタンス変数@Aを持つ  ・@Aを元に整形して標準出力する振る舞いを持つ クラスB Aの子クラスで、標準出力する内容を細かく設定するクラス  ・独自のインスタンス変数は持たない  ・親クラスのインスタンス変数@Aを編集する振る舞いを持つ 上記の実装である時、クラスBの振る舞いでクラスAのインスタンス変数@Aを編集しようとした際にエラーが発生します。 尚、レシーバはsuperです。 エラー内容 ./clsb.rb:49:in `edt_dsp': super: no superclass method `edt_dsp' (NoMethodE rror) エラー文中に出てる'edt_dsp'というメソッドが親クラスのインスタンス変数を編集するメソッドです。 尚、子クラスには独自の変数は無いのでinitializeメソッドは定義していません。 なぜこのようなエラーが発生してしまうのかわからず困っています。 現在自分でも色々とサイトを回って調べていますが、解決には至っていません。 ご回答いただければ幸いです。 以上です。よろしくお願いします。

    • ベストアンサー
    • Ruby
  • 動的に生成されるインスタンス間のやりとりについて

    あるクラスのインスタンスが動的に複数生成される状態で,一つのインスタンスから, 複数の他インスタンスのメンバ関数(仮に関数A)を呼びたいと考えています. そこでstaticなインスタンスのリストのようなものを設けようと考えました. 各インスタンスの関数Aへ関数ポインタの配列を定義し, それによって上記を実現しようと思いました. しかし,インスタンス生成前にインスタンス名を指定して (instance_name_.*p)(); という様に呼べるわけもなく,どう動的にインスタンスのリストを保持するかが思いつきません. 説明が下手ですいません.どなたか教えていただけますでしょうか. よろしくお願いします. 環境 Windows XP, cygwin