Are abstract methods and pure virtual functions the same thing? - c++

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.

Related

Abstract Classes in 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.

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.

Set a virtual function declaration to zero? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why pure virtual function is initialized by 0?
In C++, what does it mean to set a function declaration to zero? I'm guessing it has to do with the function being virtual, and not actually defined in this class. Found in a header file of code that I'm reading:
virtual void SetValue(double val)=0;
What's going on here?
It's a pure virtual function. It makes it so you MUST derive a class (and implement said function) in order to use it.
This is called a pure virtual member function in C++ lingo. It means, as you guessed, that the function is not defined within the class, but rather has to be implemented in deriving classes. You cannot instantiate classes with pure virtual member functions, pure virtual functions basically behave like abstract methods in Java or C#.
It means that it is a pure virtual method - which means subclasses must implement the method on their own. There can still be an implementation for that method, but classes with pure virtual methods cannot be instantiated, making this similar to the abstract keyword seen in various other languages.
if you set a virtual function to set, Its called Pure Virtual Functions. And then your class becomes an abstract class.
You can't create instances of that class or any subclasses unless your pure virtual functions are implemented.
The method SetValue is pure virtual. Its class does not provide the implementation of that method, and can not be instantiated (therefore we term it abstract). Concrete derived classes on the other hand have to provide implementations for such methods. See more here.
It means that, the class is abstract, and can't be create its object. It could be used as a base class to another. Pure virtual class is also used in c++ as an interface known from language like java, but of course it is different.
As everyone has mentioned, this means that the function is a pure virtual function. Think of of this as setting the function pointer to null. Classes with pure virtual functions are handled as abstract classes. This means that derived classes must implement this virtual function.
Occasionally, you may encounter what is called a "pure call" error. This means that a pure virtual function was actually called and it will most likely cause the program to crash. The most common cause of a pure call is that the object that the function was called on was already deleted.
"SetValue" is a pure virtual member function that the base class forces derived classes to provide. Pure virtual member functions will have no implementation.
A pure virtual member function specifies that a member function will exist on every object of a concrete derived class even though the member function is not (normally) defined in the base class.
This is because the syntax for specifying a pure virtual member function forces derived classes to implement the member function if the derived classes intend to be instantiated (that is, if they intend to be concrete).
In your case, all objects of classes derived from the base class will have the member function SetValue(). However, because the base class is an abstract concept, it does not contain enough information to implement SetValue().
Imagine that the "= 0" is like saying "the code for this function is at the NULL pointer."
Pure virtual member functions allow users to write code against an interface for which there are several functionally different variants. This means that semantically different objects can be passed to a function if these objects are all under the umbrella of the same abstract base class.