Why can't we create objects for an abstract class in C ++?

I know this is forbidden in C ++, but why? What if this were resolved, what would be the problems?

+6
c ++ object abstract-class
source share
9 answers

Judging by your other question , it seems you don't understand how classes work. Classes are a set of functions that work with data.

functions themselves do not contain memory in the class. Next class:

struct dumb_class { void foo(){} void bar(){} void baz(){} // .. for all eternity int i; }; 

It has an int size. No matter how many functions you have, this class will only take up the space needed to work with int . When you call a function in this class, the compiler will give you a pointer to the place where the data is stored in the class; this is a pointer to this .

So, the function somewhere lies in memory, is loaded once at the beginning of your program and is waiting for a call with data to work.

Virtual functions are different. The C ++ standard does not define how virtual functions should behave, only what should be in this case. Typically, implementations use what is called a virtual table, or vtable for short. Vtable is a table of function pointers that, like ordinary functions, are allocated only once.

Take this class and suppose our constructor uses vtables:

 struct base { virtual void foo(void); }; struct derived { virtual void foo(void); }; 

The compiler will need to create two vtables, one for the base and one for the derived. They will look something like this:

 typedef /* some generic function pointer type */ func_ptr; func_ptr __baseTable[] = {&base::foo}; func_ptr __derivedTable[] = {&derived::foo}; 

How does he use this table? When you instantiate the class above, the compiler slides with a hidden pointer that points to the correct vtable. Therefore, when you say:

 derived d; base* b = &d; b->foo(); 

When the last row is executed, it goes to the correct table ( __derivedTable in this case), goes to the correct index (in this case, 0) and calls this function. As you can see, this will cause a call to derived::foo , which is what should happen.

Note that in the future this is the same as derived::foo(b) , passing b as the this pointer.

So, when virtual methods are present, the size class will increase by one pointer (pointer to vtable.) Multiple inheritance will change a little, but basically it's the same thing. You can get more information on the C ++ - FAQ .

Now, to your question. I have:

 struct base { virtual void foo(void) = 0; }; // notice the = 0 struct derived { virtual void foo(void); }; 

and base::foo has no implementation. This makes the pure abstract base::foo function. So, if I called it as stated above:

 derived d; base* b = &d; base::foo(b); 

What behavior should we expect? Being a pure virtual method, base::foo does not even exist. The above code is undefined behavior and can do anything: from nothing to failure, with anything in between. (Or worse.)

Think of what an abstract abstract function is. Remember that functions do not take data; they describe how to manipulate data. A pure abstract function states: "I want to call this method and manipulate my data. How you do it is up to you."

So, when you say: β€œWell, let me call an abstract method,” you respond to the above: β€œBefore me? No, you do it.” to which he will reply "@ ​​# ^ @ # ^". It just doesn't make sense to tell someone who says "do it," "no."

To answer your question directly:

"why can't we create an object for an abstract class?"

Hopefully now you see that abstract classes define only the functionality that a particular class should have. The abstract class itself is just a blue font; you do not live in blue prints, you live in houses that produce blue prints.

+22
source share

The problem is this:

  • What should a program do when an abstract method is called?
  • and worse: what should be returned for a non-void function ?

An application that could cause a crash or throw an exception at runtime can cause problems. You cannot fictitiously perform any abstract function.

+5
source share

A class can simply be declared abstract, where it does not have abstract methods. I suppose this could be illustrated theoretically, but the class developer does not want you to do this. This may have unintended consequences.

Usually abstract classes have abstract methods. They cannot be created for the simple reason that they skip these methods.

+3
source share

Because logically this makes no sense.

An abstract class is an incomplete description.
This indicates what needs to be filled in order to make it complete, but without the bit being completed.

My first example is a chess game:
The game has many pieces of various types (King, Queen, Pawn ... etc.).

But there are no real objects of type, but all objects are instances of objects obtained from a piece. How can you have an object that is not fully defined. It makes no sense to create a piece object, since the game does not know how it moves (this is the abstract part). He knows that he can move, but not in the way he does.

+3
source share

Abstract classes are by definition unsafe. They require specific classes to be obtained. What else could be an abstract class if it does not have pure virtual (unrealized) functions?

+2
source share

Why can't we create an object of an abstract class?

just an abstract class contains abstract methods (means functions that do not have a body), and we cannot give functionality to abstract methods. And if we try to give functionality to abstract methods, then there will be no difference between the abstract class and the virtual class. So, if we create an object of the abstrast class, then it makes no sense to call useless functions or abstract methods, since they are without functionality. Therefore, therefore, any language does not allow us to create an object of an abstract class.

+1
source share

Abstract classes created by instances will be useless because you will see much more "pure virtual function". :)

It looks like: we all know that the car will have 3 pedals, a steering wheel and a gear. Now, if that were the case, and there would be a case with three pedals and a gear and a wheel, I do not buy it, I need a car, for example, with seats, doors, AC, etc. With pedals that really do something other than existence and that the abstract class does not promise me, those who implement it.

0
source share

This is the same class of questions as why I cannot change the value of the const variable, why I cannot access the private members of the class from other classes, or why I cannot override the final methods.

Because the purpose of these keywords does not allow you to do this. Because the author of the code is considered so dangerous, unwanted, or simply impossible because of some abstract reasons, such as the lack of essential functions that need to be added by specific child classes. In fact, you cannot create an instance because the class is virtual. This is because an inability to instantiate a class defines it as virtual (and if a class that cannot be created is not virtual, it is a mistake. The same thing happens if an instance of this class makes sense, it should not be marked as virtual)

0
source share

Basically, creating an object is responsible for allocating memory for member variables and member functions. but here, in a pure virtual function, we declare and define in a derived class. Creating an object generates an error.

0
source share

All Articles