0

現在、私はJavaからC ++に切り替えていますが、これは私に苦労を与えています(しかし、多くの新しい経験^^)。私は自分のプログラムの構成を含むいくつかのデータ転送オブジェクトを書いています。いくつかのクラスを作成しましたが、コンテナのように動作するクラスが必要です。

コンテナのヘッダーは次のとおりです。

class MyContainer{

public:
MyContainer();
virtual ~MyContainer();

Config getConfig(TypeEnum type) {
    switch (type) {
    case ATYPE:
        return config_a;
    case BTYPE:
        return config_b;
    default:
        break;
    }

}

ConfigA config_a;
    ConfigB config_b;
};

構成にはいくつかのデータが含まれており、別の構成ファイルから派生しています。

そしてここにC++があります-出典:

 MyContainer::MyContainer(){
  ConfigA config_a(int c = 1);
  ConfigB config_b(double b = 2.1);
  this->config_a = config_a;
  this->config_b = config_b;
}

いくつか問題があると思います。しかし、私にとっての主な質問は 、このコンテナー内のこれらの構成を取得して、プログラムの他のモジュールと共有するにはどうすればよいですか?config_aをポインタにしようとしましたが、これらのタイプが一致しないというエラーメッセージが常に表示されます。

 this->config_a = &config_a; //If ConfigA config_a; was ConfigA *config_a; instead

getConfigもう少し時間があれば、 -Methodがこのように機能するかどうか教えてください。

そして、これについて別のトピックがある場合は、共有してください。ありがとう。

4

2 に答える 2

1
  1. ヘッダーに書き込むConfigA configAと、コンテナークラスの割り当て中にconfigAが自動的に割り当てられます。したがって、次のように初期化する必要はありません。

    ConfigA config_a(1);
    this->config_a = config_a;
    

    代わりに、次のことを行うことができます。

    this->config_a->value = 1;
    
  2. 書く必要はありません:

    ConfigA config_a(int c = 1);
    

    簡単に言うと、言及されているint c = 1のは次のような操作です。

    • 一時変数c用にヒープにスペースを割り当てます(これはメソッドを入力するときにも実行できます)
    • それに値を割り当てます。これには、右側の値を返すという副作用があります。
    • 返された右側の値は、ConfigAコンストラクターに適用されます。

    これを理解するには、次のことを試してください。

    int a, b, c;
    c = (a = 2) + (b = 8);
    printf("a = %d, b = %d, c = %d\n", a, b, c);
    
  3. 構成を別のモジュールに渡す場合は、次のいずれかの解決策を選択できます。

    a)構成を参照として受け入れます(構成クラスは同じ基本クラスから派生する必要があります)。

    ConfigA & configA = dynamic_cast<ConfigA &>(container.get_config(ATYPE));
    

    この場合、コンテナは次の方法で構成を返します。

    return this->configA;
    

    ただし、ヘッダーは変更する必要があります。

    Config & getConfig(TypeEnum type) { (...)
    

    b)構成をポインターとして受け入れます(上記と同じ)

    ConfigA * configA = dynamic_cast<ConfigA *>(container.get_config(ATYPE));
    

    この場合、コンテナは次の方法で構成を返します。

    return &(this->configA);
    

最後に、これは私がそれを行う方法です:

class ConfigA
{
private:
    int i;

public:
    int GetI() const { return i; }
    void SetI(int newI) { i = newI; }
};

class ConfigB
{
private:
    float f;

public:
    float GetF() const { return f; }
    void SetF(float newF) { f = newF; }
};

class Config
{
private:
    ConfigA configA;
    ConfigB configB;

public:
    ConfigA & GetConfigA() { return configA; }
    ConfigB & GetConfigB() { return configB; }
};

class AppContext
{
private:
    Config config;

public:
    Config & GetConfig() { return config; }
};

// Somewhere in the code

Config & config = context.GetConfig();
ConfigA & configA = config.GetConfigA();
configA.SetI(44);

const-correctnessも言及する価値がありますが、OPの演習として残しておきます;)

于 2013-01-02T13:23:22.667 に答える
1

あなたのコード:

ConfigA config_a(int c = 1);

ConfigAを返し、デフォルト値が1のintを受け取る関数プロトタイプを意味します。ただし、int宣言を式から分離すると、次のように変更されます。

int c;
ConfigA config_a(c = 1); //  This is construction of a ConfigA object

私は次のようにコンストラクターを書きます:

MyContainer::MyContainer(int c = 1, double d = 2.1)
 :    config_a (c), config_b (d)  //  Construct the members in the intialization line
{
}

これらのメンバーへのポインターを共有する場合は、次のようなポインターを返します。

ConfigA * MyContainer::GetConfigA(){return &config_a;}
ConfigB * MyContainer::GetConfigB(){return &config_b;}

ただし、ポインタメンバーを操作する場合は、次のようにします。

 MyContainer::MyContainer(int c = 1, double d = 2.1)
 :    pConfig_a (new ConfigA (c)), pConfig_b (new ConfigB (d))
{
}


ConfigA * MyContainer::GetConfigA(){return pConfig_a;}
ConfigB * MyContainer::GetConfigB(){return pConfig_b;}


 MyContainer::~MyContainer()
{
    delete pConfig_a;
    delete pConfig_b;
}
于 2013-01-02T13:39:50.117 に答える