2012-01-16 15 views
1

I持って、次の抽象クラス抽象クラスのメンバは、派生クラスで設定された値にアクセスすることはできません

class Language { 
    const std::string name ; 

    protected: 
    std::string cmd, home ; 
    Config::Section cfg ; 

    bool load_conf() { 
     home = env("HOME") ; 

     // DEBUG 
     std::cout << home << std::endl ; 
     std::cout << name << std::endl ; 

     if (!cfg.load(home + "/.cr", name)) { 
      std::cerr << "cr: No configuration found for this language." << std::endl ; 
      return false ; 
     } 

     return true ; 
    } 

    public:   
    virtual bool handles(const std::string) = 0 ; 
    virtual int run(std::string) = 0 ; 
} ; 

し、それを

class Python : public Language { 
    const std::string name ; 

    public: 
    Python() : name("python") {} 

    bool handles(const std::string) ; 
    int run(std::string) ; 
}; 

問題を実装して、このような派生クラス、数私が持っているのはnameが空であると報告されたにあります。これは設定がうまくいてもエラーを吐き出します。 load_conf()は、それぞれの派生クラスによって実装されるrun()から呼び出されます。

私はnameを保護し公開しようとしましたが、どちらも違いはありません。理想的には、抽象クラス(保護されている)にnameを宣言したいだけで、派生クラスごとに宣言を繰り返す必要はありませんが、コンパイルはしません。私もthis->nameを使ってみましたが、それも空です。そして、constも削除しても差はありません。

私はそれがスコープの問題だと感じていますが、私は何が欠けていますか?

答えて

6

単一の引数を受け入れるコンストラクタを宣言します。コンストラクタは、nameに初期化する値を渡して派生ctorsに渡します。ここ

は一例です:次のような

class Language { 
    const std::string name ; 
}; 

class Python : public Language { 
    const std::string name ; // <-- this is different, and frankly redundant 
}; 

何かがあなたが参照する場合は上記...

class Language { 
    const std::string name ; 
    Language(std::string some_name) : name(some_name) {} // <-- set the name 
}; 

class Python : public Language { 
    Python() : Language("python") {} // construct the base with the name... 
}; 
+0

ありがとう、完璧です –

1

あなたは既に基本クラスLanguagenameという名前の変数を持って交換する必要があります〜nameload_conf()内のコンパイラは、基底クラスnameを参照し、変数nameを派生しません。

単純な解決策は、2つの変数に別々の名前を持っているか、
そう各派生クラスは、この変数を参照することができるprotectedように、ベースクラスでnameを作ることです。

0

class Pythonフィールドnameは、load_confで参照されていないフィールドを上書きしています。

はあなたのLanguageクラスprotectednameを作成し、そのサブクラス内の1つを削除し、それがうまく動作するはずです。