Abstract Classes in C++ - c++

How do we know if a class in C++ is abstract just by looking at it's definition?
I mean, in Java, there would be an abstract keyword included in the class name. In C++, all we have is pure virtual functions...well, even then if a class derives an abstract base class (with pure virtual funcs) but fails to provide implementation for those functions (meaning that the derived class is also abstract), we wouldn't even know if the derived class is abstract just by looking at it as it would not contain any pure virtual functions and yet it's abstract.
So, what's the deal here?

There is no way to tell from the definition whether or not a class is abstract, apart from looking for pure virtual functions like you said.

As such the standard doesn't use any special keywords for abstract classes in C++, the only way to know is the presence of at least one pure virtual function in the class.

In C++11 use is_abstract(), before there is the same function in boost.

Related

How to declare a class explicity abstract?

I am looking at the following:
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr142.htm
and it says an abstract class in C++ contains a pure virtual function. However, surely this does not mean to create an abstract class all I do is insert a pure virtual function? Couldn't I have the situation where I have a concrete class which doesn't provide an implementation for one particular function and therefore makes it abstract, forcing derived classes to provide the implementation? This wouldn't make the class abstract though?
So how do I differentiate between "this is an abstract class" and "this is a concrete class with one pure virtual function"?
A class is extactly then abstract when it has one or more pure virtual function. If you write a (base) class, wich has all functions implemented, and thus can be instantiated, but it misses a vital function, then it is simply wrong design of your class.
Your base class wouldn't be complete in this case and the pure virtual uninmplemented function should be added, which makes it an abstract class then.
If you have a derived class, which derives from an abstract class, and doesn't implement all functions from the base class, then it is in turn also abstract. In this case, it wouldn't need a pure virtual function itself, because it is abstract by inheritance.
There is no abstract keyword in C++, like in Java to indicate that a class is abstract.
As already stated above, an abstract class in C++ is, by definition, a class which has at least one pure virtual function. The class being abstract means that you can't make instances of it (only of "concrete" classes derived from it), which protects you from calling the "unexistent" pure virtual functions (although technically you can still call them from base class constructor/destructor and get a nasty runtime crash).
There are no explicit "interface" kind of classes in C++, so you are free to provide implementation for some functions in any classes as you wish, regardless of whether the class is already abstract due to some other function being pure virtual.
On a side note, I'd still like to point out one way to make your class abstract without actually making any "real" methods pure virtual. It is enough to make the class destructor pure virtual (note that it is generally a good idea for the destructor of any polymorphic class to be virtual anyway). A minor gotcha here is that in this particular case (only for destructor), you will still have to provide an implementation for it for the linker to be happy. It may look like this:
class A // abstract class
{
public:
virtual ~A() = 0 {} // destructor is pure virtual, but still needs a body
};
class B : public A {}; // concrete class deriving from an abstract class
Also note that in this particular case, class B does not have to explicitly implement its own destructor to become concrete, so, if you'd like it to be abstract too, you'll have to repeat the same trick again (or add some other pure virtual methods to B).

What is the difference between abstract class and pure abstract class in C++?

Example:
Iterators are pure abstractions: Anything that behaves like an
iterator is an iterator.
What does it mean?
An abstract class has at least one pure virtual function. This is standard C++ terminology.
Some people use the term pure abstract class to describe a class that has nothing but pure virtual functions (in other words, no data members and no concrete functions). This is equivalent to Java interfaces.
Now to your actual question:
Iterators are pure abstractions: Anything that behaves like an iterator is an iterator.
This has nothing to do with abstract classes (pure or otherwise). All it's saying is that anything that fulfils the iterator contract is an iterator. It doesn't even have to be a class (think pointers).
Nothing. The C++ Standard states only that a), a class is abstract if it has at least one pure virtual function, direct or inherited, and b), you can't instantiate an abstract class directly. There's no such thing as a pure abstract class.
I would think a pure abstract class is the C++ equivalent of an interface.
See here:
A pure Abstract class has only abstract member functions and no data
or concrete member functions. In general, a pure abstract class is
used to define an interface and is intended to be inherited by
concrete classes. It's a way of forcing a contract between the class
designer and the users of that class. The users of this class must
declare a matching member function for the class to compile.
An abstract class is a class with some functionality but some that needs to be implemented, whereas a pure abstract class has none of its functionality implemented.
This is a bit like an interface in other languages such as C# and Java.
A pure abstract class would serve the purpose of specifying a 'contract' that concretions of the pure abstract class must adhere to.
Abstract Class *will atleast have one pure virtual function and can have data members.
Pure Abstract Class is just like an interface. Only pure virtual functions can be defined here. No data members or method definition can be done here.
For more information visit: (https://en.wikibooks.org/wiki/C%2B%2B_Programming/Classes/Abstract_Classes/Pure_Abstract_Classes)
In C++ there is not pure abstract class. There are only abstract class and pure virtual function (function has been marked with = 0). Class with at least one pure virtual function becomes abstract. However pure virtual function can have implementation.
In your example, you're talking about Iterators. In C++, and more specifically in the standard library, the term Iterators doesn't refer to a pure abstract class but to what are called concepts. Concepts are used with templates rather than with virtual/inheritance-based polymorphism. Currently (C++11), concepts are only defined in the library documentation, i.e. they do not (yet) exist as part of the C++ language itself. The standard library documents concepts, for example the "Iterator" concept, as a set of requirements for any type/object to be accepted as a type parameter of a template that wants to work with an "Iterator". A set of requirements is defined in terms of which expressions are valid on an object, regardless of its type. It's a form of duck-typing. For example, see : http://en.cppreference.com/w/cpp/concept/Iterator

Can a base class implementation stand in for a pure virtual method of an interface?

Say I have CFooer and it implements method void foo().
I then have ISomething that has virtual void foo() = 0.
I now create a class:
class CSuperFoo : public CBase, public CFooer, public ISomething
{
};
When I instance CSuperFoo, will I get a cannot instance abstract class error, or would this use CFooer's implementation to satisfy ISomething. If this does not work, why doesn't it?
Thanks
You will have to provide an implementation in the Derived class CSuperFoo to be able to create objects of it, otherwise it will be an Abstract class.
The method foo() from the Base class ISomething needs to be overridden in the deriving class CSuperFoo explicitly because compiler cannot see any relation between method from class CFooer and ISomething::foo() as there is no relation between CFooer & ISomething, SO it demands the specific method being implemented in the derived class so that it is not an Abstract class anymore.
Does'nt work on Ideone.
If CFooer virtually inherits from ISomething I believe it should work ok (I didn't test it). If it doesn't inherit virtually then it will be treated as two distinct methods, and the abstract one will need to be overridden.
Typically in C++ one doesn't use inheritance to implement an interface though and see this code seems like a code smell at first glance. There might be a better, more C++ idiomatic approach if you gave us more details.
Short answer: No you cannot instantiate it.
Explanation:
First you cannot instantiate a abstract class. An abstract class is a class that has a pure virtual function. You know that. Now any class that derives from this abstract class is still abstract until it implements those pure virtual functions. So if I SuperFoo inherits from ISomething, then until it implements the pure virtual functions declared in ISomething, SuperFoo will stay abstract. Now you may think that well, CFooer implements that pure virtual function declared in ISomething, and hence SuperFoo implements it. But if you think that then your forgetting something, namely function hiding, see, now SuperFoo definition of the pure virtual function gets hidden from the function prototype in ISomething, hence the pure virtual function needs to be defined. All of this assumes CFooer inherits from ISomething, since it has the same function definition and if not then your doing it wrong, actually you probably should even be in this situation.
One more thing to add is that if CFooer does inherit from ISomething, as it probably should, then there is no need for ISomething to be part of CSuperFoo. You can simply declare the defined function in CFooer as virtual and then again implement it in SuperFoo. There are also more problems that are possible depending on the minor detail of your code, such are the need for virtual inheritance.
As per the C++ FAQ this is "legal, but not moral".
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.8
Essentially, you will "hide" the CFooer::foo() by implementing a virtual or non-virtual method with the same name foo in the derived class.
There are different cases to consider here. The first thing is what is the exact meaning of your sentence: CFooer implements method void foo(). If the meaning of that sentence is that there is a function with the same signature of the pure abstract function in ISomething, then that is not implementing the function on the interface.
If CFooer, on the other hand derives from ISomething interface, then CFooer::foo does implement the function and provides a final overrider. The problem is that because CSuperFoo derives from both CFooer and ISomething, it contains two different subobjects of type ISomething, and CFooer is only providing a final-overrider for one of them, and CSuperFooer is still abstract.
If that is the case, changing the inheritance both in CFooer and CSuperFooer from ISomething to virtual will solve the issue (virtual inheritance is designed so that even if the type is mentioned in different levels or branches of the hierarchy tree, all of those that are marked as virtual represent a single unique object. CSuperFooer will have a single ISomething subobject, and the final overrider can be that of CFooer.

Are abstract methods and pure virtual functions the same thing?

As far as I know, both abstract methods and pure virtual functions do NOT provide any functionality ... So can we say they're both the same thing ?
Also, suppose a class (not necessarily declared as abstract) contains a number of implemented methods (not abstract or virtual), but contains a pure virtual function. Is this class then abstract ?
Yes, they are the same thing. In C++, an abstract method is just another way of describing the characteristics of a pure virtual function. Both just mean a method with no implementation provided that needs to be implemented in a sub-class before the class can actually be instantiated.
The situation with pure virtual functions and abstract classes in C++ is similar as they essentially mean exactly the same thing. Any abstract class must have at least 1 pure virtual function or else it could be instantiated and wouldn't be abstract. Likewise, any class with at least 1 pure virtual function must be abstract because it needs to be extended so that method can actually be implemented.
Therefore, a class is abstract if and only if it contains at least 1 pure virtual function/abstract method.
Later on, languages like Java and C# made things like this more explicit, allowing a special keyword to define a class abstract rather than the presence of a pure-virtual function. C++ lets you do the same things as these languages, but they're just a little more explicit about it. :D
You don't explicitly declare classes or methods as abstract in C++. The presence of pure virtual methods is what makes them abstract.
Yes, abstract methods are the exact same thing as pure virtual functions; the terms are often used interchangeably. IMO, "Pure virtual function" is the C++ technically correct term which specifically denotes the fact that the function is set to 0:
class myClass {
public:
virtual void vfunc() = 0; // pure specifier
};
An abstract class is defined by:
a class that is designed to be
specifically used as a base class. An
abstract class contains at least one
pure virtual function.
So basically, an abstract class is an abstract class because it's designed to be a base class (some base classes by definition need to have implementable methods which will need to be pure virtual). These classes become abstract classes simply by how they are used and extended from. Unlike languages like Java, there is no abstract or interface keyword modifier so this is why we need a "verbal contract" to talk about abstract classes in C++.
In C++, a pure virtual member function leads to the enclosing type being an "abstract type".
Functions themselves cannot be abstract, though the term is frequently misused in this manner.
I would say yes, abstract methods and pure virtual functions are conceptually the same thing.
Also, suppose a class (not necessarily declared as abstract) contains a number of implemented methods (not abstract or virtual), but contains a pure virtual function. Is this class then abstract ?
A class with at least 1 pure virtual function is called an abstract class.

How to define an interface in C++?

I'm working on a C++ class which provides an abstraction of BSD sockets for networking. I want to define an interface ISocket which is implemented by CSocket and MockSocket (the latter for unit testing). I know that I need to define the methods that I want implementing classes to provide as pure virtual, i.e.
class ISocket {
public:
virtual int Socket(int domain, int type, int protocol) = 0;
};
What I'm worried about is whether a class of type ISocket can be instantiated. My instincts tell me that any class with at least one pure virtual method is an abstract class (i.e. interface) and cannot be instantiated, but I have a niggling worry in the back of my mind that I need to do something about the auto-generated constructors and destructor that the C++ compiler will provide (Effective C++ is both a gift--when you remember everything you read in it--and a curse--when you don't).
Am I doing this correctly, or is there a best practise for defining interfaces in C++ that I'm not following here?
In general, you should declare a virtual destructor; otherwise you'll get into undefined behaviour if you try to invoke delete on a pointer-to-interface. There are no such issues with constructors.
Oh, and you are correct that it is not possible to instantiate an object of a class with a pure-virtual.
My instincts tell me that any class with at least one pure virtual method is an abstract class (i.e. interface) and cannot be instantiated
Your instincts are correct on this one. Types with at least one pure virtual function can't be instantiated and will generate a compiler error.
You are doing correct:An abstract class is a class that is designed to be specifically used as a base class. An abstract class contains at least one pure virtual function. You cannot instantiate a virtual class.
You are correct in thinking that any class with a pure virtual method is abstract and cannot be instantiated.
Personally I tend to add a protected destructor to most of my interfaces as in many/most cases I don't want the code that uses the interface to be able to destroy it. Alternatively you should add a public virtual destructor (not pure, with an empty body!) so that the object can be deleted via the interface pointer and the correct destructors will be called.