Domanda

I have “Cannot allocate an object of abstract type” error.

I get it when I create an object Be (inheriting from abstract class Ae) when passing it to a method taking const Ae&. I thought it shouldn't be a problem when passing as a reference. The error says: error: allocating an object of abstract class type Be.

The logic of a program goes as follows:

//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() );
    }
};

What is wrong with my code?

To clarify the goal of such structures - AUser is CsvFile, BUser is ParticularCsvFile (with methods recognizing which field contains which datatype), A is CsvFileExceotion, B is ParticularFileException, Ae is ErrorCode, Be is for example ErrorWhenReadingPricesCell

The error pops out for line containing throw Exception( B::Be() ); claming additionally that note: unimplemented pure virtual method 'message' in 'Be' public: virtual const char* message() const = 0;

Edit

As requested, the exact g++ -Wall -pedantic -Wextra goes below. Please note that I simplified the code above and changed names: 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
È stato utile?

Soluzione

After fixing several typo-type of grammar errors, such as changing from

class Ae

to

struct Ae

,

from

struct Be

to

struct Be : public Ae

,

from

A Exception( const Ae& e )

to

A Exception( const A::Ae& e )

The code compiled perfectly in clang, so I don't get your question. Did you at least try to compile your code posted in this question?

Altri suggerimenti

Oh it's obvious!

Exception for some reason is a function that returns an A

Here:

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;

we have a virtual method here.

then

            throw Exception( B::Be() );

means "throw an A that results form Exception's function call"

but you CANNOT throw an A! Because A is abstract

additionally

exception expects a Ae, but you give it a Be, and no conversion between the two.

The compiler has actually found like 4 errors here, that's why the report is so useless (I'll be posing to the GCC mailing list the question of why it is so useless)

Be does not inherit from anything

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

See

It seems that you didn't actually implement some abstract method declared in class A in class B. If there is an unimplemented abstract method, then the class itself (B) remains abstract. It is a compilation error to try to create a new instance of an abstract class (since the compiler would not know what to do if it got a call to that unimplemented method). Check that all abstract methods declared in A are implemented in B, and you should be fine...

To further hone in on your erro:

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

class Ae has declared that message() is virtual... Class B is not implementing this virtual method, struct Be is. struct Be is a part of B, it's not itself extending Ae. Therefore the method is unimplemented as part of B... Not sure why this is being downvoted...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top