clang ++:无法分配抽象类型的对象

时间:2014-01-07 01:00:44

标签: c++ inheritance abstract-class virtual-method

我有“无法分配抽象类型的对象”错误。

当我将对象Be(从抽象类Ae继承)传递给采用const Ae&的方法时,我得到了它。我认为作为参考传递时不应该是一个问题。错误说明:error: allocating an object of abstract class type Be

程序的逻辑如下:

//A.hpp
struct A : public std::exception { //Exception class
    class Ae { //Error message class
        virtual const char* message() const = 0;
        inline operator const char*() const {
            return message();
        }
    };
    // fields describing where the error occurred in file input
    int a, b, c, d;
    // string reporting what happened
    const char* msg;
    A( const Ae& e, int a, int b, int c, int d ) : a(a), b(b), c(c), d(d), msg(e)
    {}
    const char* what() const throw() { /* printing some nice report */ }
    ~A() throw () {}
};

//B.hpp 
struct B : public A {
    B( const Ae& e, int a, int b, int c, int d ) : A( e,a,b,c,d )
    {}
    struct Be : public Ae { //particular error having relevant class name e.g. IncorrectInput
        const char* message() const {
            return "Some error description";
        }
    }; // more of alikes
};

//AUser.hpp
struct AUser { // some module that will be throwing A
    int a, b, c, d;
    A Exception( const Ae& e ) {
        return A( e, a, b, c, d );
    }
};

//BUser.hpp
struct BUser : public AUser {
    void fun() { // any method
        // (...) does sth
        if ( goeswrong )
            throw Exception( B::Be() );
    }
};

我的代码出了什么问题?

澄清此类结构的目标 - AUser是CsvFile,BUser是ParticularCsvFile(方法识别哪个字段包含哪种数据类型),A是CsvFileExceotion,B是ParticularFileException,Ae是ErrorCode,Be是例如ErrorWhenReadingPricesCell

除了throw Exception( B::Be() );

之外,还会弹出包含note: unimplemented pure virtual method 'message' in 'Be' public: virtual const char* message() const = 0;的行的错误

修改

根据要求,完全 g ++ -Wall -pedantic -Wextra如下所示。 请注意,我简化了上面的代码并更改了名称: BUser == DividendsFile,B == DividendsFileReadingException,Be == UnexpectedStockDividend,AUser == CsvFile,A == CsvFileReadingException,Be == ErrorCode

quotreader2.cpp:18:5: warning: unused parameter ‘argc’ [-Wunused-parameter]
Input/DividendsFile.cpp: In member function ‘int DividendsFile::getStockDividend()’:
Input/DividendsFile.cpp:28:85: error: cannot allocate an object of abstract type ‘DividendsFileReadingException::UnexpectedStockDividend’
In file included from Input/DividendsFile.cpp:3:0:
Input/Exceptions/DividendsFileReadingException.hpp:28:12: note:   because the following virtual functions are pure within ‘DividendsFileReadingException::UnexpectedStockDividend’:
In file included from Input/CsvFile.hpp:4:0,
                 from Input/DividendsFile.hpp:4,
                 from Input/DividendsFile.cpp:2:
Input/Exceptions/CsvFileReadingException.hpp:17:37: note:   virtual const char* CsvFileReadingException::ErrorCode::message() const
make: *** [bin/test.bin] Error 1

3 个答案:

答案 0 :(得分:0)

哦,很明显!

由于某种原因,异常是一个返回A

的函数

下面:

A Exception( const Ae& e ) {
    return A( e, a, b, c, d );
}

AAAAnnnnd

struct A : public std::exception { //Exception class
    class Ae { //Error message class
        virtual const char* message() const = 0;

我们这里有一个虚拟方法。

然后

            throw Exception( B::Be() );

表示“抛出A形成异常函数调用的结果”

但你不能扔A!因为A是抽象的

另外

异常需要一个Ae,但你给它一个Be,并且两者之间没有转换。

编译器实际上在这里发现了4个错误,这就是报告如此无用的原因(我将向GCC邮件列表提出为什么它如此无用的问题)

Be不会继承任何内容

struct Be { //particular error having relevant class name e.g. IncorrectInput
    const char* message() const {
        return "Some error description";
    }
}; // more of alikes

答案 1 :(得分:0)

修复了几个错字类型的语法错误,例如改变

class Ae

struct Ae

struct Be

struct Be : public Ae

A Exception( const Ae& e )

A Exception( const A::Ae& e )

代码在clang中完美编译,所以我没有得到你的问题。您是否至少尝试编译此问题中发布的代码?

答案 2 :(得分:-1)

似乎你实际上没有实现在类B中的A类中声明的一些抽象方法。如果有一个未实现的抽象方法,那么类本身(B)仍然是抽象的。尝试创建抽象类的新实例是一个编译错误(因为如果调用该未实现的方法,编译器将不知道该怎么做)。检查A中声明的所有抽象方法是否都在B中实现,你应该没问题......

进一步磨练你的错误:

struct Be { //particular error having relevant class name e.g. IncorrectInput
        const char* message() const {
            return "Some error description";
        }
    }; 

类Ae声明message()是虚拟的...... B类没有实现这个虚方法,struct Be是。 struct Be是B的一部分,它本身并不延伸Ae。因此,该方法未被实施作为B的一部分...不确定为什么这被贬低...