【问题标题】:Why can I not overload this base class method?为什么我不能重载这个基​​类方法?
【发布时间】:2012-05-08 15:10:27
【问题描述】:

所以,我有一个基类:

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

【问题讨论】:

  • 编译得很好 - ideone.com/vse9u
  • @luke 好点,但析构函数问题只对std::string* s = new ShaderComparable很重要
  • @Holland 因为代码可以编译。
  • @luke。 (今天早上来自 Pedantic 先生)只有在通过删除指向 std::string 的指针上删除时才会泄漏。静态/自动和删除指针(ComparableType*(或派生指针)类型)将被正确销毁。
  • @LuchianGrigore 如果您实例化 ShaderComparable 代码是否仍然可以编译(他肯定会这样做)?我猜不是因为他没有提供基类中纯虚函数的实现。函数签名需要匹配。

标签: c++ operator-overloading multiple-inheritance


【解决方案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;
        }
    }
};

【讨论】:

  • 如果他同时控制了Comparable 基类和从它派生的东西,这也可能是双重调度的候选者
【解决方案2】:

当你实现 final overrider 时,参数列表必须与基类相同。你的不是。这是一个简化的例子:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    • 1970-01-01
    • 2011-07-09
    • 2018-09-18
    相关资源
    最近更新 更多