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;
    }
4

2 回答 2

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;
    };
};
于 2012-05-08T15:49:39.770 回答
1

唯一的问题是,由于某种原因,我无法从基类重载运算符函数以接受 ShaderComparable 的类型,而不仅仅是 Comparable。有没有解决的办法?

您不能以这种方式“重载”虚拟功能。派生类(或其子类之一)必须实现所有纯虚函数,这要求参数完全匹配。

你可以做的是使用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;
        }
    }
};
于 2012-05-08T15:50:00.317 回答