How to declare a class explicity abstract? - c++

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).

Related

Turning a non-pure virtual function into pure in a subclass

So, I have this polymorphic hierarchy:
ClassA
Is not abstract, no pure virtual functions, but a few virtual functions
ClassB:public ClassA
Defines an extended interface for a certain type of subclass;
is abstract with pure virtual functions
ClassC:public ClassB
Usable class, no more subclassing
Here's the deal, I will have objects of ClassA and ClassC thrown together into containers and iterated through. To perform this iteration, a non-pure virtual function is present in ClassA but is empty with just {}; that is, it is empty, made available only if the iteration encounters a ClassC in which case it is invoked, otherwise it does nothing. I can't have it be pure otherwise I cannot have objects of ClassA.
But to ensure that ClassC does in fact implement that function, forcing the user of that class to do so, I make this function pure virtual in ClassB.
Is this acceptable? Nothing will "break" if I take a non-pure virtual function, make it pure, then make it non-pure again in ClassC ?
You're fine if implemented as you present in your explanation. Without going into entire sections on abstract base classes and virtual functions, the standard dictates:
C++ § 10.4p2
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. [ Note: Such a function might be inherited: see below. — end note ] A virtual function is specified pure by using a pure-specifier (9.2) in the function declaration in the class definition. A pure virtual function need be defined only if called with, or as if with (12.4), the qualified-id syntax (5.1)
The "below" referenced above leads to this note:
C++11 § 10.4p5
[Note: An abstract class can be derived from a class that is not abstract, and a pure virtual function may override a virtual function which is not pure. - end note]
a non-pure virtual function is present in ClassA but not implemented;
That results in linker error. When creating an objects of ClassA or its subclasses, all virtual methods must be implemented. Only for pure virtual methods the body of the method is optional.
But to ensure that ClassC does in fact implement that function,
forcing the user of that class to do so, I make this function pure
virtual in ClassB.
Yes, this way is correct. But, you should also evaluate that, is it worth having a new class just to make sure that few methods are implemented or not?
For C++11, you can think of making smart use of override identifier as well.
Also, you should not worry about the internal details of vtable, as they are implementation defined.

Abstract base class implementation

Here is an interview question :
How can we implement an abstract base class without using pure virtual functions.
What we can do so that we cannot create any object of a class because in that case we can say our class is an abstract base class.
At first I thought of using an virtual destructor but I am not sure about this solution because of virtual keyword. Can you please help?
You ask two questions, which we will answer in turn:
How can we implement an abstract base class without using pure virtual functions?
It is impossible, per the definition of an abstract class: "A class is abstract if it has at least one pure virtual function" (C++11 §10.4/2). Therefore, in order to be abstract, a class must declare a pure virtual function or it must inherit one from another class from which it derives.
What we can do so that we cannot create any object of a class?
This question can be interpreted in a number of different ways, each of which has a different solution.
Taken literally, the question asks for a type of which no instance may be created. A class with no defined constructors cannot be constructed.
To accomplish this, one should declare (but not define) a default constructor and copy constructor for the class. If one is using a compiler with support for C++11's deleted special member functions, they should be declared as deleted.
Taken in the context of the first question, it seems more likely that the intent is to define a class that can only be instantiated as a base class subobject of another class.
This can be accomplished by declaring all constructors as protected, not providing any static factory member function that creates instances of the class, and by not befriending any other classes or functions.
A virtual destrutor won't do the required job.You can do either of the following:
Declare a pure virtual destructor with a definition.
Make constructor of the base class protected.
for more clear explanation refer to Making a class abstract without any pure virtual methods.

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.