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.
Related
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).
I need to understand these statements:
virtual string FOOy() = 0;
virtual string FOOx( bool FOOBAR ) = 0;
I am not sure if the function being virtual has anything to do with it...
Although your testcase is woefully incomplete, from the presence of the keyword virtual it looks like this is inside a class definition.
In such a context, = 0 is not an assignment at all, but a piece of confusing syntax that marks the virtual member function as being "pure". A pure virtual member function may have an implementation (defined elsewhere), but one is optional and the function's very existence prohibits the class from being instantiated.
That is, a class with pure virtual member functions may be called "abstract".
Your peer-reviewed C++ book covers the topic in much greater detail.
It means that the method is pure, or abstract. It means that the method is meant to be declared by extending classes (thanks for clarifying this--see comments below).
The = 0 syntax is how you declare a pure virtual function in C++. A pure virtual has no implementation in the class declaring it -- any subclass must implement the function in order to be instantiable.
http://www2.research.att.com/~bs/glossary.html#Gpure-virtual-function
That makes the function a pure virtual function. This means that the class that declares the function is abstract, and subclasses must provide an implementation for this function.
By adding the = 0 you are declaring the virtual function to be pure virtual function. This means that derived classes must implement the method before they can be instantiated. Normally the base class does not have implementation.
This is also called an abstract function in other languages, such as Java and C#.
It simply means, that the implementor (Original writer) of the class in which FOOx and FOOy intended it to be used as an interfaces to its Derived Classes.
And these being virtual means, it will be possible that the derived class' implementation will be used, using the base class' pointer. So its being usable as an interface becomes possible by declaring them as virtual.
And finally, answering your question. Value-assignment, specifically assigning 0 to a function means, explicitly saying, that function doesn't has any definition. (Though you can specify a definition for it, but it will need to be called explicitly by the derived classes)
If a function is declared non-virtual in a derived class when the base class function was virutal, why does it invoke a vtable lookup on calling the function on its pointer? The function is clear from the scope.
In C++ if you declare a method virtual in the base class then it's virtual also in derived class, even if the virtual keyword is omitted.
For documentation purposes is however in my opinion nice to repeat it anyway.
You cannot make a function non-virtual, so it will stay virtual and a call to the function is in general also virtual. Of course, there are situations where the compiler will be able to optimize this and do a direct call, but apparantly not in your scenario.
The function is still virtual (assuming it has the same or a covariant signature). Using virtual when overriding is redundant.
Virtual methods created to affect on derived class (When you mark a method as virtual. It will use vtable on derived classes). And the overrided methods will be virtual.
When a class inherits a virtual function, any new, overriding declaration of that function will automatically be made virtual, even if the virtual keyword is not used.
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.
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.