2012-05-08 54 views
1

所以,我有一個基類:爲什麼我不能重載這個基​​類方法?

enum ComparableType 
{ 
    CompType_ShaderObject 
}; 

class Comparable 
{ 
public: 
    Comparable(void) {}; 
    Comparable(ComparableType ct) : mComparableType(ct) 
    {} 
    inline virtual std::string& getKey(void) = 0; 
    virtual ComparableType getType(void) = 0; 
protected: 
    virtual ~Comparable(void){ } ; 
protected: 
    virtual bool operator>(const Comparable& isLessThan) = 0; 
    virtual bool operator<(const Comparable& isGreaterThan) = 0; 
    virtual bool operator>=(const Comparable& isLessThanOrEqualTo) = 0; 
    virtual bool operator<=(const Comparable& isGreaterThanOrEqualTo) = 0; 
    virtual bool operator==(const Comparable& isEqualTo) = 0; 
    virtual bool operator!=(const Comparable& isNotEqualTo) = 0; 

protected: 
    ComparableType mComparableType; 

}; 

充當以下基礎:

class ShaderComparable : public Comparable, public std::string 
    { 
    public: 
     ShaderComparable(void) { }; 
     ShaderComparable(const char* shaderFilename); 
     ~ShaderComparable(void); 

    public: 
     inline std::string& getKey(void) { return mFilename; } 
     inline ComparableType getType(void) { return mComparableType; } 

    public: 
     virtual bool operator>(const ShaderComparable& isLessThan); 
     virtual bool operator<(const ShaderComparable& isGreaterThan); 
     virtual bool operator>=(const ShaderComparable& isLessThanOrEqualTo); 
     virtual bool operator<=(const ShaderComparable& isGreaterThanOrEqualTo); 
     virtual bool operator==(const ShaderComparable& isEqualTo); 
     virtual bool operator!=(const ShaderComparable& isNotEqualTo); 
    private: 
     inline bool isSameType(const ShaderComparable& objectToCheck) { return mComparableType == CompType_ShaderObject; } 
     std::string mFilename; 
    }; 

唯一的問題是,由於某種原因,我不能超載來自基類的操作符函數接受類型ShaderComparable,而不僅僅是Comparable。有沒有解決的辦法?

我的錯誤是:

>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(26): error C2653: 'ShaderComparable' : is not a class or namespace name 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(26): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(26): error C2143: syntax error : missing ',' before '&' 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(33): error C2653: 'ShaderComparable' : is not a class or namespace name 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(33): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(33): error C2143: syntax error : missing ',' before '&' 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(39): error C2653: 'ShaderComparable' : is not a class or namespace name 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(39): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(39): error C2143: syntax error : missing ',' before '&' 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(44): error C2653: 'ShaderComparable' : is not a class or namespace name 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(44): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(44): error C2143: syntax error : missing ',' before '&' 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(49): error C2653: 'ShaderComparable' : is not a class or namespace name 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(49): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(49): error C2143: syntax error : missing ',' before '&' 

更新

這是源文件,它是來自:

ShaderComparable::ShaderComparable(const char* shaderFilename) 
     : Comparable(CompType_ShaderObject), 
      mFilename(shaderFilename) 
    {} 

    ShaderComparable::~ShaderComparable(void) 
    { 
    } 

    bool ShaderComparable::operator>(const ShaderComparable& isLessThan) 
    { 
     std::string toCompare = std::string(); 

     if(toCompare.compare(mFilename) > 0) 
      return true; 
     else 
      return false; 
     } 
    } 

    bool ShaderComparable::operator<(const ShaderComparable& isGreaterThan) 
    { 

     std::string toCompare = std::string(); 
     return true; 
    } 

    bool ShaderComparable::operator>=(const ShaderComparable& isLessThanOrEqualTo) 
    { 

     return false; 
    } 

    bool ShaderComparable::operator<=(const ShaderComparable& isGreaterThanOrEqualTo) 
    { 
     return false; 
    } 

    bool ShaderComparable::operator==(const ShaderComparable& isEqualTo) 
    { 
     return false; 
    } 

    bool ShaderComparable::operator!=(const ShaderComparable& isNotEqualTo) 
    { 
     return false; 
    } 
+1

編譯就好了 - http://ideone.com/vse9u –

+0

兩件事情......你比較操作的函數簽名不基地之間的匹配和派生類。這將導致事情不像你所期望的那樣工作。其次,不要從標準庫容器派生(本例中爲std :: string)。它們的析構函數不是虛擬的,所以派生類在被銷燬時會泄漏。 – luke

+0

@luke不,它是UB。你不知道他們會泄漏。 –

回答

1

唯一的問題是,由於某種原因,我無法過載從基類的 操作功能接受 ShaderComparable的類型,而不是隻是可比。有沒有辦法圍繞 這個?

你不能用這種方式「重載」虛擬功能。派生類(或其子類之一)必須實現所有純虛函數,並且要求參數完全匹配。

你可以做的是使用dynamic_cast

struct A 
{ 
    virtual void foo(A&) = 0; 
}; 

struct B : public A 
{ 
    virtual void foo(A& myA) 
    { 
     try 
     { 
      B& myB = dynamic_cast<B&>(myA); // dynamic_cast is what you want, but be aware it has runtime overhead 
      // do something 'B' specific, with myB 
     } 
     catch (const std::bad_cast& e) 
     { 
      std::cerr << e.what() << std::endl; 
      std::cerr << "This object is not of type B" << std::endl; 
     } 
    } 
}; 
+0

如果他掌握了基礎「可比」類以及從中派生出來的東西,那麼這也可能是雙派遣的候選人 – tmpearce

1

當你實現最終超控器,參數列表必須與基類相同。你的不是。下面是一個簡化的例子:

class Base 
{ 
public: 
    virtual Base& foo(const Base& obj) = 0; 
}; 

class Der : public Base 
{ 
public: 
    void Base& foo(const Der& obj) 
    { 
     return * this; 
    }; 
}; 

int main() { 
    Base* p = new Der; 

    return 0; 

} 

該代碼是不合法的,因爲Der::foo()需要Der參考作爲參數,而不是一個Base參考。這是合法的:

class Der : public Base 
{ 
public: 
    void Base& foo(const Base& obj) 
    { 
     return * this; 
    }; 
}; 

順便說一句,即使參數列表必須與基類的聲明,返回類型不必相同。但它必須是共同的變體。所以,這也是合法的:

class Der : public Base 
{ 
public: 
    void Der& foo(const Base& obj) 
    { 
     return * this; 
    }; 
}; 
相關問題