【问题标题】:C++ - "Cannot declare parameter 'anonymous' to be of abstract type"C++ - “不能将参数‘匿名’声明为抽象类型”
【发布时间】:2015-09-11 03:54:07
【问题描述】:

我有这个简单的类(Alpha)和他的抽象类(Beta)。我无法将 Alpha (Beta) 对象传递给 overwrite() 函数,因为抽象类无法处理自类型对象。

#include <iostream>
using std::cout;
using std::endl;
using std::ostream;

class Beta {
    public:
        virtual int  read() const = 0;
        virtual void write(int) = 0;
        virtual void overwrite(Beta) = 0; // <-- This is the problem
};

class Alpha : public Beta {
    public:
        int  read     () const;
        void write    (int);
        void overwrite(Alpha);
    private:
        int value;
};

int Alpha::read() const {
    return value;
}
void Alpha::write(int v) {
    value = v;
}
void Alpha::overwrite(Alpha A) {
    value = A.value;
}

int main () {
    Alpha A, B;
    A.write(8);
    B.write(6);

    cout << "A: " << A.read() << endl; // 8
    cout << "B: " << B.read() << endl; // 6

    A.overwrite(B);

    cout << endl << "A: " << A.read(); // 6
    return 0;
}

它给了我[Error] cannot declare parameter '&lt;anonymous&gt;' to be of abstract type 'Beta'。如何处理?这是一个小代码示例,但我需要解决这个问题,因为我无法重载运算符并正确声明该类型的函数。

【问题讨论】:

    标签: c++ class inheritance abstract


    【解决方案1】:

    Beta 类是抽象的,不能被实例化。

    您的函数签名需要一个抽象类的实例化。

    尝试通过引用或指针传递:

    void overwrite(Beta& b);
    void overwrite(Beta * b);
    

    【讨论】:

    • 我做到了,它显示了一个不同的错误:无法将变量“A”声明为抽象类型“Alpha”,因为以下虚函数在“Alpha”中是纯的:virtual void Beta::覆盖(Beta&)
    • @AndroidGuy 如果您不更改Alpha::overwrite 的签名,这正是我告诉您的情况。
    • 呃抱歉,我没听懂。
    • @AndroidGuy:您的Alpha 类是抽象的,因为它没有正确 实现overwrite 方法。编译器说overwrite(Alpha a) 是与overwrite(Beta&amp; b) 不同的方法。你的Alpha 类需要有一个overwrite(Beta&amp; b) 方法。
    • 好的,我明白了。谢谢你的解释。
    【解决方案2】:

    问题是你的overwrite 方法是纯虚拟的,没有被覆盖。这个方法在Beta中有如下签名

    virtual void overwrite(Beta) = 0;
    

    Alpha

    void overwrite(Alpha);
    

    这些不是相同的函数签名。例如,您可以做的是传递一个引用并将其转换为

    class Beta {
        public:
            virtual int  read() const = 0;
            virtual void write(int) = 0;
            virtual void overwrite(Beta&) = 0;
    };
    
    class Alpha : public Beta {
        public:
            int  read     () const;
            void write    (int);
            void overwrite(Beta&) override;  // Note the override
        private:
            int value;
    };
    
    void Alpha::overwrite(Beta& A){
        value = static_cast<Alpha&>(A).value;
    }
    

    这将产生输出 (live demo):

    A: 8
    B: 6
    
    A: 6 
    

    请注意,我在Alpha 中的函数声明之后添加了关键字override。如果您在参数仍然是 Alpha 时执行此操作,那么您的代码将不会因此而编译。

    【讨论】:

    • 这是一个不错的答案,但在我的情况下,不应触及 Alpha 类,尤其是在提及其中的抽象类的情况下。如果只接触抽象类(Beta)就可以解决,那就太好了。
    • 那么你就是 SOL。如果您无法更改派生类中overwrite 的签名以匹配基类中的纯虚函数,那么您将无法编译任何派生类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    相关资源
    最近更新 更多