2009-09-04 12 views
1

私は現在、後で実装される抽象的なインターフェイスを持つC++プロジェクトに取り組んでいます。また、実装には実装されていないメソッドも実装されています。 私の問題は、私の実装を使用すると、コンパイラ(MSVC)はインターフェイスメソッドを見ないということです。これを引き起こす原因は何ですか?どうすれば解決できますか?実装に仮想メソッドがありません

ここにコードがあります。

#include <string> 
#include <vector> 
using std::string; 

class A 
{ 
    public: 
    string name; 
}; 

class interface 
{ 
public: 
    virtual int num_foo() = 0; 
    virtual A* foo(int) = 0; 
    virtual A* foo(string &name){ 
     for (int i(0); i < num_foo(); i++) 
      if (foo(i)->name == name) 
       return foo(i); 
     return 0; 
    } 
}; 

class implementation : public interface 
{ 
public: 
    virtual int num_foo() { return m_foos.size(); } 
    virtual A* foo(int i) { 
     //check range 
     return &m_foos[i]; 
    } 
    std::vector<A> m_foos; 
}; 

int main(...) 
{ 
    implementation impl; 
    // impl is properly initialized here 

    string name("bar"); 
    // here comes my problem, the MSVC compiler doesn't see foo(string &name) 
    // and gives an error 
    A *a = impl.foo(name); 
} 
+2

私はそれを見ているし、私のエディタにコードを貼り付けましたが、私は半分に固定した後、私はそれをあきらめましたダースのエラーとそれはまだコンパイルされませんでした。あなたが求めている問題が1つしかないコードを提供することはとても難しいですか?それは、私が何十というエラーのどれをあなたが不平を言うのか見ることができません。コードを修正してください。 – sbi

+1

申し訳ありません、悪いコードです。私は今、エラーを修正して、今私の問題が存在します。 –

答えて

5

名前解決は、過負荷解決前に行われます。 impl.foo(name)では、コンパイラはimplementationクラスを調べ、virtual A& foo(int i)しか見つけません。それは、それが正しい名前の関数を見つけたので、基本クラスを見ません。

これを修正するには、オーバーロード解決のために、派生クラスにfooのすべての基本バージョンを取得する宣言を追加することができます。通常、私はオーバーロードされた関数を避けることを望み、おそらくfooのバリアントに異なる関数名を与えるでしょう。

;

(あなたが参照に->の代わり.を使用しようとすると、あなたはAへの参照を返す関数に0を返すようにしようとする他のエラーは、あなたがstringvectorm_ones定義しないということです。)オーバーロードのためのサブクラスで

+0

+1と2つの提案された回避策があります。 – RichieHindle

+0

私の質問に答えることに感謝し、最初に提供された悪いコードを予知します。 –

3

(例えばFOO(列)など)を再発行ベースの方法、クラスの実装に

using interface::foo; 

を加えます。

+0

素早く良い答えをありがとう! –

1
class implementation : public interface{ 
    public: 
     using interface::foo; 
     int num_foo() { return m_foos.size(); } 
     A& foo(int i) 
     { //check range 
      return m_ones[i]; 
     } 
     vector<A> m_foos; 
     vector<A> m_ones; 
}; 
0

あなたは@チャールズ・ベイリーによって答えに、既に述べたように、fooメンバーを持っているimplementationインターフェイスを、アクセスしているので、これが唯一の問題です。あなたは、おそらく実際にそれを呼び出す必要がありますので

意味的に、何を呼び出そうとしているのはinterfaceメソッドfooは、次のとおりです。これはまた、あなたがプライベートimplementation::fooを行うことによって、Non-Virtual Interface idiomを実装できるようになる

int main() 
{ 
    implementation impl; 
    string name("bar"); 
    interface& interf = impl; 
    A *a = interf.foo(name); 
    A *b = interf.foo(4); 
} 

impl.fooを直接呼び出そうとすると失敗しますが、同じエラーですべての引数タイプに失敗します。

(私はこの質問が古いですけど、NVIが古いです...)

関連する問題