This question already has answers here:
What is the difference between a concrete class and an abstract class?
(9 answers)
Closed 5 years ago.
I am in the process of reading "The C++ Programming Language 4th Edition" and I've gotten to the point where Bjarne is trying to explain concrete classes. His explanation is confusing me, and I cannot find any explanation online that satisfies me. I understand that abstract classes are classes that have at least one virtual function and that concrete classes are the opposite, but I can not wrap my head around concrete classes. The book "Programming Principles and Practice using C++" is saying that a concrete class is essentially a derived class, and an abstract class is a base class. Is this the correct interpretation? I have been trying to figure out this concept all day. Also, "a class that can be used to create objects is a concrete class". Does this mean that a class is concrete if I can do something like "myclass classobject1;", and I am not able to make objects with abstract classes?
Essentially, a concrete class is a class that implements an interface. An interface, such as an abstract class, defines how you can interact with an instance that implements that interface. You interact with an instance through member functions, so an interface typically declares virtual member functions that are meant to be overridden (implemented) by an implementing class (concrete class). If I have an abstract class Animal, it might have a virtual member function named speak. Animals all make different sounds, so the Animal interface does not know how to define that function. It will be up to the concrete classes, such as Dog, or Tiger, to define what actually happens when the speak function is invoked.
Related
Every time I add a non-concrete virtual method to an abstract class, the compiler gives unuseful error invalid new-expression of abstract class type '...' on all the classes that derives from that abstract class, and then I need to do git diff to search for the new method I added earlier, or look for the note in GCC's errors. (there can be days difference between adding the method, and compiling)
Can I specify in C++ that a class must be concrete (and if it's not tell the cause/missing-method)?
Answering the question at hand:
Can I specify in C++ that a class must be concrete (and if it's not tell the cause/missing-method)?
C++ has no explicit abstract or concrete classes. These concepts are implicit in the language. Abstract is implied by the presence (either in the class itself or inherited) of one or more pure virtual member functions, and concrete by the absence of such functions.
This is exactly how the C++ standard defines an abstract class (§13.4/2)
[class.abstract]
An abstract class is a class that can be used only as a base class of some other class; no objects of an abstract class can be created except as subobjects of a class derived from it. A class is abstract if it has at least one pure virtual function.
There's no keyword such as Java's abstract, for example, in C++.
Compiler error messages are the standard place where you can catch errors such as the attempt to instantiate a class that still has pure virtual member functions.
This question already has answers here:
object of abstract class type "Connection" is not allowed
(3 answers)
Closed 8 years ago.
I have problem using class base with pure virtual method.
The method should be virtual.
I get this error:
Error: object of abstract class type "Membro" is not allowed: function "Membro::mensalidade" is a pure virtual function
Anyone can help?
Thanks!
The problem is clear from the error message: you may not instantiate an object of an abstract class.
However it seems that there is no need to create an object of the abstract class in the function you showed. As I have understood the function searches an object with the given string bi. You could use a lambda expression in some search method.
That is the problem is that the design of the function is incorrect.
To get more exact answer you should show the function and what is the type of membros.
Just like the error says Membro::mensalidade is a pure virtual function. This means you cannot use Membro directly but you have to implement it in a subclass and reimplement at least all the pure virtual methods.
If a class contains at least one pure virtual function, then that class is abstract. That means you cannot create object of that class. Abstract classes serves as interface classes to more derived class.
However, you can define that pure virtual function. But this feature is of limited use except to impress your fellow workers.
You cannot instantiate an abstract class.
Any class is abstract if it contains at least one one pure-virtual method (e.g. anything with =0; at the end of the function signature).
You must instantiate a class derived from the abstract class (which must implement the pure-virtual function(s) to not be abstract itself) instead and return a pointer to that. The pointer's type can be the type of the abstract class, and the object that it points to must be a subclass of the abstract class, allowing you to access the derived classes polymorphically.
You have to imeplement the virtual method in a derived class. It is pure virtual to make sure that you implement it when deriving from the class. It also means that there is no default implementaion of that method.
This kind of class has a name they are called Abstract Classes. or Interfaces.
It might be a silly question but I never saw a question about it or read about it.
Imagine that we have this:
class Numeric
{
public:
virtual ~Numeric() {}
virtual int getNumeric() const = 0;
};
This is considered an interface.
And now I insert an enumerator (It can be something else, like a typedef, etc.)
class Numeric
{
public:
enum Numbers
{
One,
Two,
};
virtual Numbers getNumeric() const = 0;
};
Still being an interface or it is now considered an abstract class?
As I said, it might be silly but I really wonder to know that.
If you are looking for an official answer, then I'm afraid there is none.
The draft of the C++11 standard I am having here merely says [10.4 class.abstract]:
An abstract class can also be used to define an interface for which
derived classes provide a variety of implementations.
All other instances of the word "interface" in the entire ~1300 pages PDF only refer to generic programming or other things not related to OOP or abstract classes.
For example this one here [24.2.1 iterator.requirements.general]:
Most of the library’s algorithmic templates that operate on data
structures have interfaces that use ranges.
This obviously has nothing to do with abstract classes.
Bjarne Stroustrup himself, if you accept his words as "half-official", doesn't really help you in this regard, either. Quoting from the glossary on his homepage:
abstract class - a class defining an interface only; used as a base
class.
You will have to live with the fact that the C++ language itself as well as C++ developers and experts use the word "interface" as a superset for "abstract class". Unlike e.g. in Java, where interfaces are an actual language element with its own interface keyword, there is no such thing in C++.
Everything else is opinion-based.
Your second class Numeric is an interface.
If a class has one or more pure virtual functions, then this class is called an "abstract class".
Generally, if all of a classes' functions are pure virtual functions, then this class is called an "interface".
C++ does not have an explicit interface concept, so the above two classes are called the interface or abstract class, somewhat interchangably.
In my opinion, your second class can be considered an interface. I don't think there is a standard which defines interfaces in C++. However in languages which have interfaces, for example, Java, you can usually have enums defined inside an interface.
I would consider a class with no implementation to be an interface.
How do you handle a "cannot instantiate abstract class" error in C++?
I have looked at some of the similar errors here and none of them seem to be exactly the same or problem that I am having. But, then again, I will admit that there are several to go over. Here is the compile error:
This leads me to this page:
http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(C2259);k(VS.ERRORLIST)&rd=true
Compile Error C2259 is from a C++ program but the page calls the abstract class an "interface":
Whenever you derive from an interface and implement the interface methods in the derived class with access permissions other than public, you may receive C2259. This occurs because the compiler expects the interface methods implemented in the derived class to have public access. When you implement the member functions for an interface with more restrictive access permissions, the compiler does not consider them to be implementations for the interface methods defined in the interface, which in turn makes the derived class an abstract class.
There are two possible workarounds for the problem:
Make the access permissions public for the implemented methods.
Use the scope resolution operator for the interface methods implemented in the derived class to qualify the implemented method name with the name of the interface.
The bad news is that I have already made all of the methods public in the class:
class AmbientOccluder: public Light {
public:
AmbientOccluder(void);
The error means there are some methods of the class that aren't implemented. You cannot instantiate such a class, so there isn't anything you can do, other than implement all of the methods of the class.
On the other hand, a common pattern is to instantiate a concrete class and assign it to a pointer of an abstract base class:
class Abstract { /* stuff */ 4};
class Derived : virtual public Abstract { /* implement Abstract's methods */ };
Abstract* pAbs = new Derived; // OK
Just an aside, to avoid memory management issues with the above line, you could consider using a smart pointer such as std::unique_ptr:
std::unique_ptr<Abstract> pAbs(new Derived);
Visual Studio's Error List pane only shows you the first line of the error. Invoke View>Output and I bet you'll see something like:
c:\path\to\your\code.cpp(42): error C2259: 'AmbientOccluder' : cannot instantiate abstract class
due to following members:
'ULONG MysteryUnimplementedMethod(void)' : is abstract
c:\path\to\some\include.h(8) : see declaration of 'MysteryUnimplementedMethod'
An abstract class cannot be instantiated by definition. In order to use this class, you must create a concrete subclass which implements all virtual functions of the class. In this case, you most likely have not implemented all the virtual functions declared in Light. This means that AmbientOccluder defaults to an abstract class. For us to further help you, you should include the details of the Light class.
Provide implementation for any pure virtual functions that the class has.
Why can't we create Object of Abstract Class ?
When we create a pure virtual function in Abstract class, we reserve a slot for a function in the VTABLE(studied in last topic), but doesn't put any address in that slot. Hence the VTABLE will be incomplete.
As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation of object for such class and will display an errror message whenever you try to do so.
Pure Virtual definitions
Pure Virtual functions can be given a small definition in the Abstract class, which you want all the derived classes to have. Still you cannot create object of Abstract class.
Also, the Pure Virtual function must be defined outside the class definition. If you will define it inside the class definition, complier will give an error. Inline pure virtual definition is Illegal.
In my case i declared a function in COM Control .idl file like
[id(1)] HRESULT MyMethod([in]INT param);
but not declared in my interface .h file like this
STDMETHOD(MyMethod)(INT param);
Problem solved by adding above line into my interface .h file
this might help some one .
If anyone is getting this error from a function, try using a reference to the abstract class in the parameters instead.
void something(Abstract bruh){
}
to
void something(Abstract& bruh){
}
Can't construct an abstract class, even from a subclass. Abstract classes are basically templates for other classes to be built on and don't have constructors themselves. It's kind of another way to do an interface that involves inheritance.
There's a lot of stuff online about polymorphism, and it's all dumb. C++ makes it so that you can inherit from multiple classes at the same time, so abstract classes and interfaces are the same there. I think the reason why abstract classes exist is because some languages, like Java, can only inherit/extend from one class only.
Abstract classes are quite literally an abstract concept. They are parents of classes, but only in our minds. They are an answer to a question that doesn't have a right answer. Like, "What is the predecessor to GTA?" and you'd say, "Well, there's Race n' Chase" but that's not even a correct answer because they're the same game, just with the name changed. Abstract classes are the answer to "what's the parent of that class"? Like you could say "Oh, a String is just a character array" and "a character array is just a couple iterators" and "iterators are just pointers". Abstract classes allow us to formalize these stupid answers into inheritance.
I have answered this question here..Covariant virtual functions return type problem
See if it helps for some one.
I have question that bothers me for few days.
Abstract class is a special type of class that we cannot instantiate, right?. (Which is denoted/specified by giving a "= 0" to at least one method declaration, which looks like an afterthought).
What are the extra benefits that the abstract class mechanism brings to C++, that a 'normal' base class cannot achieve?
According to the wikibooks section on abstract classes:
It's a way of forcing a contract between the class designer and the users of that class. If we wish to create a concrete class (a class that can be instantiated) from an abstract class we must declare and define a matching member function for each abstract member function of the base class.
As mentioned, it's a way of defining an interface to which derived classes must adhere. Their example of the Vehicle abstract class is very apropos: you'd never have just a Vehicle in real life, you'd have a Ford Explorer or a Toyota Prius, but those both conform to (for the sake of argument) a base set of functionality that being a Vehicle might define. But, you can't just go to the Vehicle dealership and drive a Vehicle off the lot. Thus, you'd never want to be able to construct and use a base Vehicle object where you'd really want a specialized, derived object.
This offers the best way in C++ to define an interface without any default implementation.
C++ does not have C#'s interface concept.
It's the equivalent of what Java turned into "interfaces". Basically, it implies that the class itself is not usable - you need to override all pure methods.
An example is MFC's CView class which has a pure OnDraw method - the basic CView doesn't do anything and is as such useless. You have to override OnDraw.
(Btw - it is still possible to provide an implementation for a pure method, and subclassed implementations can fall back to it, but they still have to provide their own override.)
They are used as a base class in a class hierarchy design.
Abstract classes are used to define a clean interface for all derived classes.
At design stage, abstract classes define an interface, per specification and derived classes implement the desired functionality accordingly.
Also using abstract classes instead of "normal" classes helps separating the implementation details from the interface.
A concrete class implements an interface, but the abstract class defines it. You could use a concrete class as a base class in your design but abstract classes are not meant to be used directly in code and can not be instantiated. They serve as prototype.
By using the "normal" class as you say, you have to define an implementation for all methods.
Don't think of it at the class level.
Look at the method, and think of what it should do in the default case:
virtual std::string getName() const = 0;
What would be a right implementation for this method ? There is none than I can think of.
By marking it "pure virtual", you ensure that if the user ever get an instance of a class derived from your interface, then this method will have a sensible behavior.
The only other way to do this would be a throw NotImplemented("getName"); body, but then you'd discover the issue at runtime, not at compile-time, which is not as nice :)