2012-05-08 51 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; 
    }; 
}; 
相关问题