Peter Leikauf
Peter Leikauf

Reputation: 545

C++ Conceptual Question: Why can't I use a partially finished abstract class?

I'am working on an abstract class, which later will be derived by several subclasses. However, pretty much of the functionality is non-abstract - so why can't I allocate an object of this abstract class and work with it, as long as I don't call any of the pure virtual functions? After all, the size of the abstract class is well known at compile time!?

Upvotes: 0

Views: 292

Answers (2)

JaMiT
JaMiT

Reputation: 17072

as long as I don't call any of the pure virtual functions?

Except in trivial cases, this can be impossible to prove. Let's look at an example. Suppose this is your abstract class

class Abby { virtual void fun() const = 0; };

and suppose you are able to create an Abby object for testing.

// First source file
Abby test;

In a trivial case, you literally do nothing with this object except cast it to void to avoid a compiler warning about an unused variable. In a non-trivial case, you might pass this object (by reference) to a function defined in a different file than the one where the object is created, perhaps the following function.

// Second source file
void foo(const Abby & o)
{
    o.fun();
}

This function expects an object that has Abby as a base class, and calls that object's virtual function. This works as long as it is forbidden to create an Abby object directly. If you relax this restriction, what happens? Should the compiler flag foo() as potentially broken because of what you might do in another translation unit? Should the compiler ignore the situation, leading to a runtime error?

Or maybe you would want a call to foo(test) to be flagged as making the definition of test to be invalid? This would be rather strange, to have the validity of one line (Abby test;) be dependent on what comes after it. It would also greatly limit what you could do in your test, leading compilers to ask why they bother. There is so little benefit to bending the rules this way, so why make a complicated language even more complicated?


Besides, it does not take much programming work to get the result you are looking for. Just comment out the pure virtual function.

class Abby { /* virtual void fun() const = 0; */ };

Since you're not calling it, this should not affect your code, right? If it does you could instead dummy-up the function, as in

class Abby { virtual void fun() const {} };

Revert this change once you are done testing.

Personally I might derive a class from Abby with a dummy fun() member, and use that concrete class for testing instead of the abstract class. However, the OP called that "a nuisance" in a comment.

class Concrete : public Abby { void fun() const override {} };

Upvotes: 1

0RR
0RR

Reputation: 1603

The definition of abstract class is as:

Defines an abstract type which cannot be instantiated, but can be used as a base class.

From: https://en.cppreference.com/w/cpp/language/abstract_class

To use it in another way would go against the use of abstract classes.

Abstract classes are used to represent general concepts (for example, Shape, Animal), which can be used as base classes for concrete classes (for example, Circle, Dog).

No objects of an abstract class can be created (except for base subobjects of a class derived from it) and no non-static data members of an abstract class can be declared.

See also https://timsong-cpp.github.io/cppwp/n3337/class.abstract

Upvotes: 1

Related Questions