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

唯一の問題は、何らかの理由で、Comparable だけではなく、ShaderComparable の型を受け入れるために基本クラスから演算子関数をオーバーロードできないことです。これを回避する方法はありますか?

この方法で仮想関数を「オーバーロード」することはできません。派生クラス (またはそのサブクラスの 1 つ) は、すべての純粋仮想関数を実装する必要があり、そのためには引数が正確に一致する必要があります。

あなたができることは、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 に答える
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 に答える