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)
Related
A pure virtual function isn't supposed to have a body, but I just noticed that the following code is accepted by the compiler:
class foo
{
virtual void dummy() = 0
{
cout << "hello";
}
};
So, why are pure virtual functions allowed to have a body? Also, even when the function has a body, the class still can't be instantiated, why is that?
Pure virtual function can have a body, but the fact that you declare them pure virtual is exactly to say that a derived implementation is required.
You can execute the pure virtual method from a derived method (using an explicit BaseClass::method()) but still you have to provide an implementation.
Not being able to instantiate a class with a pure virtual method that has not been overriden is the main point of the pure virtual declaration. In other words the idea of declaring a method pure virtual is to ensure that the programmer will not forget about providing its implementation.
Generally speaking, abstract class is used to define interface and/or partial implementation, and is intended to be inherited by concrete classes. It is a way of enforcing a contract between class designer and users of that class, whatever they are.
If you don't need this contract and want instantiation, then do not enforce it to be abstract class, i.e. remove = 0.
If your concern is why would pure virtual functions have body in the first place, then one good example could be this quote from the Effective C++ book by Scott Meyers:
Derived classes that implement this pure virtual function may call
this implementation somewhere in their code. If part of the code of
two different derived classes is similar then it makes sense to move
it up in the hierarchy, even if the function should be pure virtual.
Another example is pure virtual destructor (which is also a function by the way):
...
virtual ~foo() = 0;
...
foo::~foo() {} // required!
when you are required to provide implementation for it, but at the same time want to make it pure virtual in order to make the foo class abstract. So, in fact, the core of the language itself relies on this feature.
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.
I am reading some C++ text regrading Pure Virtual Functions. As the text says, the form of Pure Virtual Functions declaration, for example, is:
virtual void virtualfunctioname() = 0;
And the text explains: "Since pure virtual function has no body, the programmer must add the notation =0 for declaration of the pure virtual function in the base class."
I have tried to remove = 0;, that means I only declared virtual void virtualfunctioname(); and things worked fine.
So, why do we need to assign a 0 to the virtual function?
Thanks
If a class has any pure virtual functions, it cannot be instantiated. Also, it forces any derived classes to implement those functions, otherwise they too cannot be instantiated.
So if you remove the = 0, you'll just have a normal base class, which may be instantiated, and doesn't enforce an interface on its derived classes. You'll only get into trouble if you instantiate a base-class object (or a derived-class object with no override), and then try to invoke virtualfunctionname() on it, because there's no definition for it, so the linker will complain.
[Note, also the claim that "pure virtual functions have no body" is incorrect; you may define an implementation for a pure virtual. The class will still be abstract, though.]
If you don't declare a method as pure virtual, the compiler will assume there is an implementation of it somewhere. If you never instantiate the class that is supposed to contain those pure virtual (and abstract class to use the right terminology), you will be fine. However, if you do, the compiler will accept the code as valid and you will get a linker error later.
If you mark a method as pure virtual, the class containing it will be marked as abstract and the compiler will refuse any attempts to instantiate it.
things worked fine
I assume you meant that the code compiled and linked. However, you probably haven't defined an implementation for virtualfunctionname in the base class you declare it, so if you ever do call the base implementation you will get a linker error.
At the moment things probably work because you provide an implementation in a derived class and use that instead.
When you declare a function as pure virtual function that class which contain it will known as abstract class and no instance would be created.
Again no instance of that class would be created.This class is used for inheritance and the derived class must implement this method. otherwise compilation error will appear.
Thanks
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.
I have a question, here are two classes below:
class Base{
public:
virtual void toString(); // generic implementation
}
class Derive : public Base{
public:
( virtual ) void toString(); // specific implementation
}
The question is:
If I wanna subclass of class Derive perform polymophism using a pointer of type Base, is keyword virtual in the bracket necessary?
If the answer is no, what's the difference between member function toString of class Derive with and without virtual?
C++03 ยง10.3/2:
If a virtual member function vf is
declared in a class Base and in a
class Derived, derived directly or
indirectly from Base, a member
function vf with the same name and
same parameter list as Base::vf is
declared, then Derived::vf is also
virtual (whether or not it is so
declared) and it overrides
Base::vf.
That keyword there is strictly optional and makes no difference at all.
The virtual property is inherited from the base class and is assumed to be present even if you don't type it out.
The compiler already knows from the 'virtual' keyword in the base class that toString is a virtual method. No need to repeat it.
A function once a virtual always a virtual.
So in any event if the virtual keyword is not used in the subsequent classes, it does not prevent the function/method from being 'virtual' i.e. be overridden. So the following guideline might help from a team development point-of-view :-
If the function/method is supposed to
be overridden, always use the
'virtual' keyword. This is especially
true when used in interface / base
classes.
If the derived class is supposed to
be sub-classed further explicity
state the 'virtual' keyword for every
function/method that can be
overridden.
If the function/method in the derived
class is not supposed to be
sub-classed again, then the keyword
'virtual' is to be commented
indicating that the function/method
was overridden but there are no
further classes that override it
again. This ofcourse does not prevent
someone from overriding in the
derived class unless the class
is made final (non-derivable), but it
indicates that the method is not supposed to be
overridden.
Ex: /*virtual*/ void someFunc();
It doesn't matter to the compiler whether or not you supply the virtual keyword on derived versions of the function.
However, it's a good idea to supply it anyway, so that anyone looking at your code will be able to tell it's a virtual function.
It's a matter of good style, and the user-programmer knows what's going on. In C++0x you can use [[override]] to make it more explicit and visible. You can use [[base_check]] to force the usage of [[override]].
If you don't want or can't do that, simply use the virtual keyword.
If you derive without virtual toString, and you cast an instance of Derive back to Base, calling toString() would actually call Base's toString(), since as far as it know's that's an instance of Base.