I have been reading an article about C++ interfaces (http://accu.org/index.php/journals/233) and I am completely lost at the part where it says all the virtual member functions should be made private (the section titled "Strengthening the Separation"). It just does not make sense to me at all.
According to the author, the code is like this:
class shape {
public:
virtual ~shape();
virtual void move_x(distance x) = 0;
virtual void move_y(distance y) = 0;
virtual void rotate(angle rotation) = 0;
//...
};
class line : public shape {
public:
line(point end_point_1, point end_point_2);
//...
private:
virtual ~line();
virtual void move_x(distance x);
virtual void move_y(distance y);
virtual void rotate(angle rotation);
//...
};
So we have a pure virtual function which is public, and its implementation (in the line class) which is private.
Could anybody explain how the move_x function can be called? Its access specifier is private, it will lead to an error if I try to do this:
line my_line(point(0,0), point(1,2));
my_line.move_x(-1); // does not compile
Similarly is it correct to say that the drawing interface (see earlier in the article)cannot access these functions either?
Thank you.
The idea is that you'd use those methods via a reference or pointer to shape.
shape &s = my_line;
s.move_x(-1);
This could be justified on the grounds of "reveal only what you need to", or as a form of self-documentation. It proves that the methods are only called in the intended way.
If you have in instance of the line object, you might be tempted to call it's methods. But if the only way you can get at them is by asking for it's shape interface, then the object looks to less like an object and more like a collection of interfaces.
This makes more sense if you imagine line implementing more than one interface.
This advice is applicable to homogeneous hierarchies only -- that is, hierarchies in which derived classes introduce no new functions (except constructors maybe) and just override base class functions. In this case you obviously don't need to work with line instance directly -- only via pointer/reference to shape.
When you have less homogeneous hierarchy, this advice hasn't much sense: how would anyone apply it to cases when derived class introduces new functions, or inherits them from another base class? In this case you sometimes want to work directly with objects of derived class directly, and this advice would lead to inconveniences only.
Further development of this idea -- less radical and usable in more contexts -- Non-Virtual Interface (NVI) by Herb Sutter.
I think that the article highlights the rationale well in this quote:
Now, the only thing users can do with
line is create instances of it. All
usage must be via its interface - i.e.
shape, thus enforcing a stronger
interface/implementation separation.
Before leaving this topic, it is
important to get something straight:
the point of enforcing the
interface/implementation separation is
not to tell users what to do. Rather,
the objective is to underpin the
logical separation - the code now
explains that the key abstraction is
shape, and that line serves to provide
an implementation of shape.
That is, line is not by itself interesting. It's just an implementation of the shape interface, and there may be other implementations. You're particularly interested in the shape interface. Hence, you should only access the implementation through this interface, and not as a standalone class.
Related
I'm transitioning from c to c++ and of course, OOP which is proving more difficult than expected. The difficulty isn't understanding the core mechanics of classes and inheritance, but how to use it. I've read book on design patterns but they only show the techniques and paint a vague picture of why the techniques should be used. I am really struggling to find a use for abstract classes. Take the code below for example.
class baseClass {
public:
virtual void func1() = 0;
virtual void func2() = 0;
};
class inhClass1 : baseClass {
public:
void func1();
void func2();
};
class inhClass2 : baseClass{
public:
void func1();
void func2();
};
int main() {}
I frequently see abstract classes set up like this in design books. I understand that with this configuration the inherited classes have access to the public members of the base class. I understand that virtual functions are placeholders for the inherited classes. The problem is I still don't understand how this is useful. I'm trying to compare it to overloading functions and I'm just not seeing a practical use.
What I would really like is for someone to give the simplest example possible to illustrate why an abstract class is actually useful and the best solution for a situation. Don't get me wrong. I'm not saying there isn't a good answer. I just don't understand how to use them correctly.
Abstract classes and interfaces both allow you to define a method signature that subclasses are expected to implement: name, parameters, exceptions, and return type.
Abstract classes can provide a default implementation if a sensible one exists. This means that subclasses do not have to implement such a method; they can use the default implementation if they choose to.
Interfaces do not have such an option. Classes that implement an interface are required to implement all its methods.
In Java the distinction is clear because the language includes the keyword interface.
C++ interfaces are classes that have all virtual methods plus a pure virtual destructor.
Abstract classes and interfaces are used when you want to decouple interface from implementation. They're useful when you know you'll have several implementations to choose from or when you're writing a framework that lets clients plug in their own implementation. The interface provides a contract that clients are expected to adhere to.
One use of abstract classes is to be able to easily switch between different concrete implementations with minimal changes to your code. You do this by declaring a reference variable to the base class type. The only mention of the derived class is during creation. All other code uses the base class reference.
Abstract classes are used to provide abstract representation of some concept you want to implement hiding the details.
For example let's say I want to implement File system interface :-
At abstract level what I can think of?
class FileSystemInterface
{
virtual void openFile();
virtual void closeFile();
virtual void readFile();
virtual void writeFile();
};
At this point of time I am not thinking of anything specific like how they will be handled in windows or linux rather I am focusing on some abstract idea.
why we need interface ( pure virtual function or abstract class) in c++?
Instead of having abstract class, Can we have a base class with virtual function defined in it, and override that virtual function in derived class.
what would be the advantage and disadvantage with the above approach ( except we can create the object of the base class)?
Pure virtual functions are for when there's no sensible way to implement the function in the base class. For example:
class Shape {
public:
virtual float area() const = 0;
};
You can write derived classes like Circle and Rectangle that implement area() using the specific formulas for those kinds of shapes. But how would you implement area() in Shape itself, if it weren't pure virtual? How do you compute the area of a shape without even knowing what kind of shape it is?
If your function can be implemented (in a useful way) in the base class, then go ahead and implement it. Not all base classes need to be abstract. But some of them just inherently are abstract, like Shape.
Pure virtual functions is your way of telling the users of your class that they cannot use the class on its own, without inheriting from it.
Obviously, you can do what you describe, and the system is going to compile and work as expected. However, an pure virtual function is not a construct for the compiler; it is for humans who read your code. It is with this construct that you tell the readers of your code that they must inherit from your class, because the class is not designed to be instantiated on its own.
You use pure virtual functions in situations when there is no reasonable default implementation for a function. This tells people who implement your class that they must provide certain functionality, and the compiler helps them in detecting situations when they forgot to provide an implementation.
If, on the other hand, you provide a default implementation for a virtual function that should be implemented by a subclass, and then the users of your class library forget to provide an implementation, the problem would not be detected until run-time.
An interface give you the ability to specify a set of behaviors that
all classes that implement the interface will share in common.
Consequently, we can define variables and collections (such as arrays)
that don't have to know in advance what kind of specific object they
will hold, only that they'll hold objects that implement the
interface.
Here
As others have said, an interface is a contractual obligation to implement certain methods, properties and events [...] That's a sufficiently awesome benefit to justify the feature.
and here
(please refer to these very good explanations)
Example:
class IGui{
protected:
virtual bool OnClicked(){return false;}
virtual bool OnHover(){return false;}
virtual bool OnScrollBarChange(){return false;}
virtual bool OnTextChange(){return false;}
...
}
class IGuiButton: public IGui{
protected:
virtual bool OnClicked() = 0;
virtual bool OnHover(){
do stuff
return true;}
...
}
The point is having a commom interface for all gui types that can be (where not all virtuals need to be overridden), and then provide a lite specialization for a button, but for the button, theres must be a override for the OnClicked..
Also, I think I should make the ones a button shouldnt override private( so use private inheritance, and use that fancy "using Base::Method;" for making the specific ones protected?
There are multiple sides to the question. The first one is actually a quite interesting question:
Can a derived class have a pure virtual method that is not pure in the base?
The answer is yes, it can. With the expected (if you expected this to work) semantics: a type derived from the intermediate type must implement the virtual function not to be an abstract type. This leads to a curious circumstance, where the base is not abstract, but the derived type is... which will be surprising. Just for this, I would avoid this in a design.
Should you mark as private the members that deriving types should not override?
No, there is no reason or advantage to do that. Whether the member function is public, protected or private derived classes can override it. Any code that can call the functions through the base type will still be able to call it by casting to base. This leads to another strange thing in your design. The base class is filled with protected virtual functions, which means that they are accessible only by the derived type. This does not define an interface and cannot be used as such. If a function/class takes a reference to a IGui, or a IGuiButton it will not be able to do much, as there is no public interface. That basically means that noone will be able to call any of the events --unless you are also abusing friendship to provide access to the event handler, but you should avoid it.
So what is a proper design?
There are different alternatives. I'd recommend that before creating your own square wheel you look at those wheels that were invented in the past: look at different graphical frameworks and libraries and try to understand why they decided to design them as such. Look at the differences and try to determine what advantages/disadvantages they bring and which option matches your problem. UI is a domain where there is a lot of prior art, and chances are you will not design from scratch anything better than people in the field have done in the past --you might do it, but it is much easier to fall in the same pitfalls everyone else felt before.
I'd have to say I think what you are trying to do is poor design.
Your top level (IGui) "has everything" and then you are effectively taking stuff out as you move down the class hierarchy. The top level would normally have the common stuff and you add the differences as you move down.
You are losing the protections that a good design can give you.
Being asked to describe what a virtual function is seems to be one of the most common questions in interviews assessing basic C++ knowledge. However, after several years programming C++, I still have the uncomfortable feeling that I don't really understand how best to define what they are.
If I consult wikipedia, I see the definition of virtual function is:
"In object-oriented programming, a virtual function or virtual method is a function or method whose behaviour can be overridden within an inheriting class by a function with the same signature"
This definition seems simple and elegant, and not C++ specific. But to me it doesn't seem to capture the concept of a virtual function in C++, since surely a non-virtual function can also be overridden within an inheriting class by a function with the same signature.
If I'm asked to describe what a virtual function is informally, I say something about pointers like "it's a method such that when you call it via a base class pointer, the version of it defined in the derived class is called instead, if the pointer actually points to an instance of a derived class". This doesn't seem like a very elegant description of the concept. I know that people say this is how "polymorphism" is achieved in C++ (polymorphism, as far as I understand, roughly being the whole idea of organizing objects into hierarchies), but I don't know of a fancier way to understand or explain the mechanism than to go through the example with the pointers.
I guess I'm confused about whether the "pointer" description of virtual functions is something fundamental to their definition, or just something incidental to their implementation in C++.
I've always thought that this quote captures the essence of virtual functions:
A virtual function is a way of defining a family of related behaviors that can be customized by the entities that actual have to do those behaviors.
If you ignore all the C++-isms of virtual functions - how having virtual functions enables dynamic_cast to work for objects of the class type, how they're only treated virtually if accessed through a pointer, how virtual destructors are completely different from virtual non-destructors, etc. - I think that the above statement gets at the heart of what virtual functions are all about.
The main reason I like this statement is that it describes virtual functions in a way that decouples them from programming. You could explain virtual functions to a non-technical person using this definition by giving some concrete analogies. For example, the idea of "turning on a light" could be thought of as a virtual function because the actual mechanics of what happens when you turn on a light depends entirely on the particular light you're using (incandescent? fluorescent? LED?), but the conceptual idea is the same in each case. Of course, it's not a perfect analogy, but I think it gets the point across well enough.
More generally, IMHO, if you're ever asked to describe something informally, try as much as possible to distance yourself from the particular programming language you're using and, if at all possible, from computers at all. Try to think of the most general setting in which the concept applies, and then describe it at that level. Then again, I teach introductory CS courses, and so I have a bit of a bias toward this domain, so I have no idea how applicable this is in a job interview setting. :-)
since surely a non-virtual function can also be overridden within an inheriting class by a function with the same signature.
No thats incorrect. The function only gets redefined not overriddden in that case.
Your informal definition is a good summary of what a virtual pointer does. It sounds like you're looking to also describe how it works, but since the C++ standard doesn't specify, any "how" description would be specific to a particular implementation and not the C++ language in general.
The C++ standard is all about behavior and says almost nothing about implementation. There's even the "as-if" rule, which allows any alternate implementation that provides the same visible behavior.
"I guess I'm confused about whether the "pointer" description of virtual functions is something fundamental to their definition, or just something incidental to their implementation in C++."
It is not incidental. The concept of virtual functions works only for pointers or references.
Virtual functions are needed when the derived class method bearing the same signature that of base class is overridden to different functionality.
class Polygon
{
public:
virtual float area()
{
std::cout << "\n No formula in general \n" ;
}
virtual ~Polygon();
};
class Square
{
public:
float area()
{
std::cout << "\n Side*Side \n" ;
}
~Square();
}
Polygon* obj = new Square ;
obj -> area() ; // Ok, Square::area() is called.
Square obj1;
Polygon& temp = obj1 ; // Ok, Square::area() is called
Square obj2;
Polygon temp1 = obj2 ; // Polygon::area() is called because of object slicing.
The difference lies in how the compiler decides which implementation to "bind" to the method call when it compiles the source code. For a virtual fumction, the implementation chosen is based on the actual concrete type of the object itself, not on the type of the variable. This means that when you cast an object to a base class or interface, the implementaion which will get executed is still the implementation defined on the derived class that the object actually is.
In puesdo code
// for a virtual function
public class Animal { public virtual void Move() { Print "An animal Moved." } }
public class Dog: Animal { public void Move() { Print "A Dog Moved." } }
Animal x = new Dog();
x.Move() // this will print "A Dog Moved."
For a non-virtual function, the implementation chosen will be based on the type of the variable, which means that when you cast an object to a base class, (i.e., change the type of the variable ) the method implementation defined in the base class will be chosen by the compiler and it will get executed, not the implementation in the derived class...
// for a non-virtual function
public class Animal { public void Move() { Print "An animal Moved." } }
public class Dog: Animal { public void Move() { Print "A Dog Moved." } }
Animal x = new Dog();
x.Move() // this will print "An animal Moved."
Let's say that Beta is a subclass of Alpha, and it can either create a new method area() or it can add a virtual one.
There isn't a difference if you are talking to a Beta pointer. But if you are talking to a Alpha* which points at a Beta object, you will get Alpha's method. Unless you declare the function as virtual.
The Beta subclass has its function dispatch table, which is a copy of Alpha's table but with extra Beta methods at the end. If Beta merely overrides a method, it will go in Beta's section of the dispatch table, so references to Alpha* will not see the new method. But, if the new method is virtual, it will go in the Alpha section of Beta's class table.
More to the point, let's say you have a Circle subclass of Shape. And let's say you have a pointer to a Shape object, x, which happens to be an instance of Circle. x->area() will only see the portion of the function table that relates to Shape. If Circle does a virtual area function, it will appear in the Shape section of the table. If Circle merely overrides area, then the area method will be placed in the Circle portion of the table and the Shape * x will not see the new function.
In C++ there is only one function table per class. This is a bit confusing for people who are used to scripting language where each object has it's own dispatch table. Scripting languages are extremely inefficient in that way. Imagine all the space taken up for each object.
If an interview is about your knowledge in C++ I think there is not a sin to refer to a pointer.
You can say simply that "virtual functions is a mechanism to allow an object to express it's class behavior, even if it's accessed through a base class pointer".
More than this (if you think about "pure virtual functions") it's also a mechanism to force a whole hierarchy of classes to provide a specific method, without defining a default method implementation in the base class.
A virtual function is one where the callee decides the behaviour. A non-virtual function is one where the caller decides the behaviour.
Is that concise enough?
Although pointers are necessary for using virtual functions in C++, I would argue that pointers are incidental to the idea, and explanations that don't depend on pointers are clearer. I think that templatetypedef and Charles_Bretana hit the main idea.
The reason that pointers seem to creep in to descriptions of virtual functions is that only pointers and references can have different run-time vs. compile-time types. A variable whose type is class Foo must contain a Foo at run-time, so it doesn't matter whether a virtual function is used. But a variable whose type is class Foo * can point to any subclass of Foo, so this is the situation where virtual functions and non-virtual functions behave differently.
The Idea
The basic difference between virtual and non virtual method is when you bind the name of the method to the actual method implementation. A virtual method is bound at runtime based on the type. A non virtual function is bound at compile time.
Slightly more formerly:
A virtual method is one that can be overridden in a derived type.
Such that when the virtual method is called (via pointer or reference) runtime binding is applied to select the version of the method that is defined in the most derived version; based on the type of the actual object (being pointed at or referenced).
C++ notes
Note: A method is virtual even if you do not use the virtual keyword if an ancestor declares a method with the same signature as virtual.
Compiler aided mechanism of achieving dynamic polymorphism.
Remember that C++ also supports static polymorphism via generic programming. And function pointers have always been there as the most primitive means of implementing dynamic polymorphism.
I recently came to know that in C++ pure virtual functions can optionally have a body.
What are the real-world use cases for such functions?
The classic is a pure virtual destructor:
class abstract {
public:
virtual ~abstract() = 0;
};
abstract::~abstract() {}
You make it pure because there's nothing else to make so, and you want the class to be abstract, but you have to provide an implementation nevertheless, because the derived classes' destructors call yours explicitly. Yeah, I know, a pretty silly textbook example, but as such it's a classic. It must have been in the first edition of The C++ Programming Language.
Anyway, I can't remember ever really needing the ability to implement a pure virtual function. To me it seems the only reason this feature is there is because it would have had to be explicitly disallowed and Stroustrup didn't see a reason for that.
If you ever feel you need this feature, you're probably on the wrong track with your design.
Pure virtual functions with or without a body simply mean that the derived types must provide their own implementation.
Pure virtual function bodies in the base class are useful if your derived classes wants to call your base class implementation.
One reason that an abstract base class (with a pure virtual function) might provide an implementation for a pure virtual function it declares is to let derived classes have an easy 'default' they can choose to use. There isn't a whole lot of advantage to this over a normal virtual function that can be optionally overridden - in fact, the only real difference is that you're forcing the derived class to be explicit about using the 'default' base class implementation:
class foo {
public:
virtual int interface();
};
int foo::interface()
{
printf( "default foo::interface() called\n");
return 0;
};
class pure_foo {
public:
virtual int interface() = 0;
};
int pure_foo::interface()
{
printf( "default pure_foo::interface() called\n");
return 42;
}
//------------------------------------
class foobar : public foo {
// no need to override to get default behavior
};
class foobar2 : public pure_foo {
public:
// need to be explicit about the override, even to get default behavior
virtual int interface();
};
int foobar2::interface()
{
// foobar is lazy; it'll just use pure_foo's default
return pure_foo::interface();
}
I'm not sure there's a whole lot of benefit - maybe in cases where a design started out with an abstract class, then over time found that a lot of the derived concrete classes were implementing the same behavior, so they decided to move that behavior into a base class implementation for the pure virtual function.
I suppose it might also be reasonable to put common behavior into the pure virtual function's base class implementation that the derived classes might be expected to modify/enhance/augment.
One use case is calling the pure virtual function from the constructor or the destructor of the class.
The almighty Herb Sutter, former chair of the C++ standard committee, did give 3 scenarios where you might consider providing implementations for pure virtual methods.
Gotta say that personally – I find none of them convincing, and generally consider this to be one of C++'s semantic warts. It seems C++ goes out of its way to build and tear apart abstract-parent vtables, then briefly exposes them only during child construction/destruction, and then the community experts unanimously recommend never to use them.
The only difference of virtual function with body and pure virtual function with body is that existence of second prevent instantiation. You can't mark class abstract in c++.
This question can really be confusing when learning OOD and C++. Personally, one thing constantly coming in my head was something like:
If I needed a Pure Virtual function to also have an implementation, so why make it "Pure" in first place ? Why not just leaving it only "Virtual" and have derivatives, both benefit and override the base implementation ?
The confusion comes to the fact that many developers consider the no body/implementation as the primary goal/benefit of defining a pure virtual function. This is not true!
The absence of body is in most cases a logical consequence of having a pure virtual function. The main benefit of having a pure virtual function is defining a contract: By defining a pure virtual function, you want to force every derivative to always provide their own implementation of the function. This "contract aspect" is very important especially if you are developing something like a public API. Making the function only virtual is not so sufficient because derivatives are no longer forced to provide their own implementation, therefore you may loose the contract aspect (which can be limiting in the case of a public API).
As commonly said :
"Virtual functions can be overrided, Pure Virtual functions must be overrided."
And in most cases, contracts are abstract concepts so it doesn't make sense for the corresponding pure virtual functions to have any implementation.
But sometimes, and because life is weird, you may want to establish a strong contract among derivatives and also want them to somehow benefit from some default implementation while specifying their own behavior for the contract. Even if most book authors recommend to avoid getting yourself into these situations, the language needed to provide a safety net to prevent the worst! A simple virtual function wouldn't be enough since there might be risk of escaping the contract. So the solution C++ provided was to allow pure virtual functions to also be able to provide a default implementation.
The Sutter article cited above gives interesting use cases of having Pure Virtual functions with body.