2011-02-10 14 views
5
template <class T> 
class baseclass{ 
protected: 
    T data; 
public: 
    baseclass(){}; 
    void setData(T d); 
}; 

template<class T> 
void baseclass<T>::setT(T d){ 
    data = d; 
} 

上記は私の基本クラス、保護されたメンバ変数1つ、セッタ1つです。シンプルなテンプレート継承の問題C++

template <class T> 
class aclass : public baseclass<T> 
{ 
    public: 
     aclass(T d); 
}; 

template<class T> 
aclass<T>::aclass(T d){ 
    setData(d); <---WORKS 
    data = d; <---DOESN'T WORK 
} 

これは最初のサブクラスです。何らかの理由で、保護されたメンバ変数に直接アクセスすることはできません。しかし、セッターへのアクセスは正常に動作します。私はC + +のノブです、私は何かが明らかに欠けていると確信しています。

+0

this-> data = d ;?を書き込むと動作しますか? –

+0

「うまくいかない」という意味を具体的に教えてください。コンパイラエラーが発生していますか(もしそうであれば、どちらか)、または実行時に何もしませんか? –

+0

@Michaelはい、そうです。当然。 – jakev

答えて

8

これがうまくいかない理由は、C++テンプレートが名前解決を行う方法では奇抜です。特に、テンプレート・タイプに依存する別のクラスから継承するテンプレート・クラスを使用している場合(この場合)、コンパイラーは、その基本クラスのメンバーに直接アクセスすることはできません。見てください。これがエラーの原因です。

は、この問題を解決するには、コンパイラはdataは何とかaclass<T>のメンバーでなければならないことを知っていることを今

template<class T> 
aclass<T>::aclass(T d){ 
    setData(d); 
    this->data = d; 
} 

として、あなたのコンストラクタを書き換えることができ、それが探しているものを見つけることができます。

興味深いことに、前の行でも同じ理由でエラーが発生するはずです。なぜそれがコンパイルすることになったのか分かりません。これを修正するには、これを行うことができ、次のいずれか

template<class T> 
aclass<T>::aclass(T d){ 
    this->setData(d); 
    this->data = d; 
} 

また、あなたはaclassは、その親クラスからsetDataメソッドを継承し、コンパイラに伝えるためにusing宣言を追加することができます。クラス宣言では、この行を追加することを検討:データメンバーのためのthis->同様

template <class T> 
class aclass : public baseclass<T> 
{ 
    public: 
     aclass(T d); 

     using baseclass<T>::setData; 
}; 

を、名前setDataから来て、コンパイラは、あなたが話しているかを知ることができますどここのトリックは、それが明確なことができます。

希望すると便利です。

+0

非常に参考になりました、ありがとうございます。 – jakev

+1

dはテンプレートパラメータに依存するため、setData(d)は機能します。したがって、Tがわかるまで解決されません。その時、私たちは実際の基本クラスも知っています。 –

+0

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19 – jakev