2017-08-18 9 views
0

私はBaseDerivedという2つのクラスを持っています。 DerivedBaseから継承し、さらにいくつかの関数と変数を含みます。したがって、2つの別々のクラスを持つ必要があります。しかし、それらは1つの関数、runを共有します。仮想変数の代替

readを実行するには、以下の例ではrunに引数を渡す必要があります。この引数は、オブジェクトが参照するクラスによって異なります。どのオブジェクトがrunを呼び出すかによって、プログラムが自動的にvars_Baseまたはvars_Derivedを使用するようなreadの汎用バージョンを記述することは可能ですか?

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 

class Base 
{ 
    protected: 
    void read(std::vector<std::string>); 

    public: 
    void run(std::vector<std::string> vars) { read(vars); } 
    std::vector<std::string> vars_Base; 
}; 

void Base::read(std::vector<std::string> int_vars) 
{ 
    for (auto int_vars_it : int_vars) 
    { 
     std::cout << int_vars_it << "\n"; 
    } 
} 

class Derived : public Base 
{ 
    protected: 
    public: 
    std::vector<std::string> vars_Derived; 
    ///Here are other functions only known to Derived, not Base 
}; 

int main() 
{ 
    Base b; 
    b.vars_Base.push_back("aB"); 
    b.vars_Base.push_back("bB"); 
    b.vars_Base.push_back("cB"); 
    b.run(b.vars_Base); 

    Derived d; 
    d.vars_Derived.push_back("aD"); 
    d.vars_Derived.push_back("bD"); 
    d.vars_Derived.push_back("cD"); 
    d.run(d.vars_Derived); 

    return 0; 
} 
+4

メンバー変数のコピーを引数として渡すのはなぜですか?メンバー関数がメンバー変数を直接使用するのはなぜですか? –

+1

使用するベクターを参照する(参照する)保護された仮想関数はありますか?あるいは 'run'をvirtualにして派生クラスでそれをオーバーライドしますか? –

答えて

1

これで結果は得られますか?

class Base 
{ 
protected: 
    using vars_type = std::vector<std::string>; 

private: 
    vars_type vars_Base; 

protected: 
    virtual vars_type& get_vars() { 
     return vars_Base; 
    } 

public: 
    void push_back(const std::string& str) { 
     get_vars().push_back(str); 
    } 

    void run() 
    { 
     for (auto int_vars_it : get_vars()) { 
      std::cout << int_vars_it << " "; 
     } 
    } 
}; 

class Derived : public Base 
{ 
private: 
    vars_type vars_Derived; 

protected: 
    vars_type& get_vars() override { 
     return vars_Derived; 
    } 

public: 
    ///Here are other functions only known to Derived, not Base 
}; 

int main(int argc, char* argv[]) 
{ 
    Base b; 
    b.push_back("aB"); 
    b.push_back("bB"); 
    b.push_back("cB"); 
    b.run(); // prints aB bB cB 

    std::cout << std::endl; 

    Derived d; 
    d.push_back("aD"); 
    d.push_back("bD"); 
    d.push_back("cD"); 
    d.run(); // prints aD bD cD 

    return 0; 
} 

この場合、説明は次のとおりです。「仮想変数」はありませんが、仮想関数があります。仮想関数は、メンバ変数の「内部アクセッサ」として使用できます。派生クラスにはvars_Basevars_Derivedの両方が含まれていますが、get_vars()を使用すると、適切なインスタンスのインスタンスへのアクセスをオーバーライドできます。

あなたは役に立つと思っています。

1

ジェネリックを使わずに、問題を解決するために仮想関数を利用することができます。ここで

は(あなたのサンプルコードに適用される)仮想関数を使用してソリューションです:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 

class Base 
{ 
    protected: 
    void read(std::vector<std::string>); 

    public: 
    virtual void run() { read(vars_Base); } 
    std::vector<std::string> vars_Base; 
}; 

void Base::read(std::vector<std::string> int_vars) 
{ 
    for (auto int_vars_it : int_vars) 
    { 
     std::cout << int_vars_it << "\n"; 
    } 
} 

class Derived : public Base 
{ 
    protected: 
    public: 
    void run() override { read(vars_Derived); } 
    std::vector<std::string> vars_Derived; 
    ///Here are other functions only known to Derived, not Base 
}; 

int main() 
{ 
    Base b; 
    b.vars_Base.push_back("aB"); 
    b.vars_Base.push_back("bB"); 
    b.vars_Base.push_back("cB"); 
    b.run(); 

    Derived d; 
    d.vars_Derived.push_back("aD"); 
    d.vars_Derived.push_back("bD"); 
    d.vars_Derived.push_back("cD"); 
    d.run(); 

    return 0; 
} 

このソリューションは、クラス内vars_Baseとvars_Derivedをカプセル化することができます。

これが役に立ちます。