3

だから私はc++に不慣れで、科学的なアプリケーションのために書いています。

データは、いくつかの入力テキストファイルから読み込む必要があります。

現在、これらの入力変数をオブジェクトに格納しています。(それをinputObjと呼びましょう)。

この「inputObj」をすべてのオブジェクトに渡す必要があるのは正しいですか。グローバル変数の複雑なバージョンになっているようです。ですから、OOPのポイントを見逃しているのではないかと思います。

私は自分のプログラムのg++コンパイル可能な小さな例を作成しました:

#include<iostream>

class InputObj{
// this is the class that gets all the data
public:
void getInputs() {
    a = 1;
    b = 2;
};
int a;
int b;
};

class ExtraSolver{
//some of the work may be done in here
public:
    void doSomething(InputObj* io) {
        eA = io->a;
        eB = io->b;
        int something2 = eA+eB;
        std::cout<<something2<<std::endl;
    };  
private:
    int eA;
    int eB;

};

class MainSolver{
// I have most things happening from here

public:
void start() {
    //get inputs;
    inputObj_ = new InputObj();
    inputObj_ -> getInputs();
    myA = inputObj_->a;
    myB = inputObj_->b;

    //do some solve:
    int something = myA*myB;

    //do some extrasolve
    extraSolver_ = new ExtraSolver();
    extraSolver_ -> doSomething(inputObj_);

};
private:
InputObj* inputObj_;
ExtraSolver* extraSolver_;
int myA;
int myB;


};


int main() {
MainSolver mainSolver;
mainSolver.start();
}

質問の要約:私のオブジェクトの多くは同じ変数を使用する必要があります。私の実装はこれを達成する正しい方法ですか。

4

4 に答える 4

5

関数が正常に機能する場合は、クラスを使用しないでください。

new自動ストレージが正常に機能する場合は、を使用して動的割り当てを使用しないでください。

これがあなたがそれを書くことができる方法です:

#include<iostream>

struct inputs {
    int a;
    int b;
};

inputs getInputs() {
    return { 1, 2 };
}

void doSomething(inputs i) {
    int something2 = i.a + i.b;
    std::cout << something2 << std::endl;
}

int main() {
    //get inputs;
    inputs my_inputs = getInputs();

    //do some solve:
    int something = my_inputs.a * my_inputs.b;

    //do some extrasolve
    doSomething(my_inputs);
}

良い本を読むことをお勧めします:決定的なC++ブックガイドとリスト

于 2012-12-19T10:37:04.537 に答える
2

私の答えはあなたのコメントに基づいているでしょう

「ええ、それが本質的にグローバル変数であるとき、私はまだオブジェクトを互いに渡す感覚を持っていません。」

したがって、この「オブジェクトを渡す感覚」には練習が伴います^^が、OOがある理由のいくつかを覚えておくことが重要だと思います。

  • 目標(簡略化されたバージョン)は、コードのセグメントをmodularise増やすようにコードを作成することです。reuse毎回再定義または再割り当てせずに、複数のInputObjを作成できます
  • もう1つの目標はdata hidingカプセル化です。変数を別の関数で変更したくない場合や、内部状態を保護するためにこれらの変数をグローバルに公開したくない場合があります。

たとえば、コードの先頭でグローバル変数が宣言および初期化されたInputObjのaとbの場合、必要がない限り、値がいつでも変更されないことを確認できますか?単純なプログラムの場合はい..しかし、プログラムの規模に応じて、変数が不注意に変更される可能性もあります(したがって、予期しない動作がランダムに発生します)。aとbの初期状態を保持したい場合は、次のことを行う必要があります。それはあなた自身です(もっと一時的なグローバル変数?)

  • controlクラス/継承/操作のオーバーライド/多態性/抽象化とインターフェースを備えたレベルの抽象化と、複雑なアーキテクチャの構築を容易にするその他の概念を追加することで、コードのフローをさらに理解できます。

現在、多くの人がグローバル変数を悪と見なしていますが、適切に使用すれば、それらは優れていて便利だと思います...それ以外の場合は、足を撃つための最良の方法です。

これが、オブジェクトを渡すことに対する不安感を少しでも解消するのに役立つことを願っています:)

于 2012-12-19T11:44:40.077 に答える
1

あなたのアプローチをうまく使っているかどうかは状況に強く依存します。高速計算が必要な場合は、InputObjクラスにカプセル化メソッドを提供することはできませんが、計算速度が大幅に低下するため、これらのメソッドをお勧めします。ただし、バグを減らすために従うことができる2つのルールがあります。1)オブジェクトを変更したくない場合は、必ず「const」キーワードを慎重に使用します。

  void doSomething(InputObj * io) -> void doSomething(const InputObj * io)

2)オブジェクトの初期状態に関連するすべてのアクション(あなたの場合、私が推測できる限り、InputObjはファイルからロードされるため、このファイルをロードしないと意味がありません)をコンストラクターに移動します。

InputObj() { }
void getInputs(String filename) {
    //reading a,b from file
};

使用する:

InputObj(String filename) {
    //reading a,b from file
};
于 2012-12-19T11:34:47.300 に答える
-3

この方法でグローバル変数を実装したのは正しいですが、グローバル値をオブジェクトにカプセル化するため、アプローチは構造化されたものであり、複雑ではありません。グローバルな価値観がいたるところに広がっていないので、これはあなたのプログラムをより維持しやすくします。

グローバルオブジェクトをシングルトン(http://en.wikipedia.org/wiki/Singleton_pattern)として実装し、グローバルオブジェクトが1つだけになるようにすることで、これをさらに改善できます。

さらに、静的メンバーまたは関数を介してオブジェクトにアクセスします。そうすれば、変数として渡す必要はありませんが、プログラムのどの部分からでも簡単にアクセスできます。

このようなグローバルオブジェクトは、たとえばマルチスレッドアプリケーションではうまく機能しないことに注意する必要がありますが、そうではないことを理解しています。

また、この種のものにシングルトンを使用する必要があるかどうかについては、多くの議論があることにも注意する必要があります。SOまたはネットで「C++シングルトンvs.グローバル静的オブジェクト」を検索します

于 2012-12-19T10:47:08.927 に答える