9

私の目的は、アプリケーションの設定を保存するためのデータ構造を設定することです。

PHPでは私はただ書くでしょう...

$settings = array(
    "Fullscreen" => true,
    "Width"      => 1680,
    "Height"     => 1050,
    "Title"      => "My Application",
);

ここで、C ++で同様の構造を作成しようとしましたが、まだ異なるデータ型を処理できません。ちなみに、そのような設定データを保存するより良い方法があれば、私に知らせてください。

struct Setting{ string Key, Value; };

Setting Settings[] = {
    ("Fullscreen", "true"),     // it's acceptable to store the boolean as string
    ("Width", "1680"),          // it's not for integers as I want to use them later
    ("Height", 1050),           // would be nice but of course an error
    ("Title", "My Application") // strings aren't the problem with this implementation
};

associative arrayの構造をどのようにモデル化できflexible datatypesますか?

4

6 に答える 6

8

さまざまなデータ型を持つ連想データ構造は、まさにそれが何であるかstructです...

struct SettingsType
{
    bool Fullscreen;
    int Width;
    int Height;
    std::string Title;
} Settings = { true, 1680, 1050, "My Application" };

ここで、フィールド名が構成ファイルに表示されるため、何らかの反映が必要な場合がありますか?何かのようなもの:

SettingsSerializer x[] = { { "Fullscreen", &SettingsType::Fullscreen },
                           { "Width",      &SettingsType::Width },
                           { "Height",     &SettingsType::Height },
                           { "Title",      &Settings::Title } };

SettingsSerializerメンバーへのポインターの型に応じて異なる動作をするオーバーロードされたコンストラクターを提供する限り、そこに到達します。

于 2012-08-24T21:02:28.930 に答える
3

C++は強く型付けされた言語です。コンテナは正確に1つのタイプのオブジェクトを保持するため、デフォルトでは、標準のC++だけでは実行しようとしていることはできません。

一方、boost::variantやboost::anyのような、複数の(または任意の)タイプの1つを保持できるタイプを提供するライブラリを使用してから、アプリケーションでそのタイプのコンテナーを使用できます。

配列ではなくstd::map、設定の名前から値にマップするために使用できます。

std::map<std::string, boost::variant<bool,int,std::string> >
于 2012-08-24T21:00:38.423 に答える
2
#include <map>
#include <string>

std::map<std::string,std::string> settings;

settings.insert("Fullscreen","true");
settings.insert("Width","1680");
settings.insert("Height","1050");
settings.insert("Title","My Application");

STLを使い続けたい場合は、それを行う1つの方法である可能性があります。

于 2012-08-24T21:00:41.737 に答える
2

1つの解決策は、次のようなISettingインターフェイスを定義することです。

class ISetting{
public:
  virtual void save( IStream* stream ) = 0;
  virtual ~ISetting(){}
};

その後、設定を保存するためにマップを使用できます。

std::map< std::string, ISetting* > settings;

ブール設定の一例は次のとおりです。

class BooleanSetting : public ISetting{
private:
  bool m_value;
public:
  BooleanSetting(bool value){
    m_value = value
  }

  void save( IStream* stream ) {
    (*stream) << m_value;
  }

  virtual ~BooleanSetting(){}
};

最終的には:

settings["booleansetting"]=new BooleanSetting(true);
settings["someothersetting"]=new SomeOtherSetting("something");
于 2012-08-24T21:03:52.360 に答える
1

Settings考えられる解決策の1つは、次のようなクラスを作成することです。

class Settings {
    public:
        Settings(std::string filename);

        bool getFullscreen() { return Fullscreen; }
        // ...etc.

    private:
        bool Fullscreen;
        int Width;
        int Height;
        std::string Title;
};

これは、設定が何らかのファイルに保存されていることを前提としています。コンストラクターを実装して、選択した形式を使用して設定を読み取ることができます。もちろん、これには、他の設定を追加するためにクラスを変更する必要があるという欠点があります。

于 2012-08-24T21:22:23.547 に答える
0

あなたの質問に答えるために、あなたはあなたが望むものを使うboost::anyboost::variant、達成することができます。バリアントから始める方が良いと思います。

boost::variant<
    std::string,
    int,
    bool
  > SettingVariant;

std::map<std::string, SettingVariant> settings;

あなたの質問に答えないために、タイプレスコンテナを使用することは私がお勧めするものではありません。強い型付けは、微妙に間違ったことをしたときにコンパイラーがエラーを出すようにコードを構造化する方法を提供します。

struct ResolutionSettings {
  bool full_screen;
  size_t width;
  size_t height;
  std::string title;
};

次に、デフォルト設定を取得するための単純な無料関数。

ResolutionSettings GetDefaultResolutionSettings() {
  ResolutionSettings settings;
  settings.full_screen = true;
  settings.width = 800;
  settings.height = 600;
  settings.title = "My Application';
  return settings;
}

ディスクから設定を読み取っている場合、それは少し異なる問題です。強く型付けされた設定構造体を作成し、弱い型付けのファイルリーダーにboost::lexicalキャストを使用して、文字列変換が機能したことを検証します。

ResolutionSettings settings;
std::string str = "800";
size_t settings.width = boost::lexical_cast<size_t>(str);

すべてのディスク読み取りロジックを、他の機能と組み合わせていない別の機能でラップすることができます。

ResolutionSettings GetResolutionSettingsFromDisk();

これが最も直接的で保守が簡単だと思います(特にC ++にあまり慣れていない場合)。

于 2012-08-24T20:58:52.120 に答える