Why must we declare virtual methods as such - c++

Suppose we have a class, "Animal", and subclasses, "Cat" and "Dog".
Let's say we want to allow both "Cat" and "Dog" to make a noise (cat: "meow" - dog: "woof") when we pass their objects into an intermediate function for any "Animal".
Why must we use a virtual method to do this? Couldn't we just do Animal->makeNoise() without defining a virtual method in "Animal"? As "Cat" and "Dog" are both animals, wouldn't it be clear that "makeNoise()" is referring to the Animal which has been passed to the function?
Is this just a matter of syntax or something more? I'm pretty sure in Java we don't have to do this.

In Java, all member functions are virtual by default (except static, private, and final ones).
In C++, all member functions are non-virtual by default. Making functions virtual adds overhead - both runtime and to object size - and the C++ philosophy is don't pay for what you don't use. Most of my objects are not polymorphic, so I shouldn't have to pay for polymorphism unless I need it. Since you need Animal::makeNoise() to be virtual, you must explicitly specify it as such.

C++ is designed to run with as little overhead as possible, trusting the programmer to make the correct call. Essentially, it 'gives you the gun and the option to shoot yourself in the foot', as one of my friends likes to say often. Speed and flexibility are paramount.
To correctly cause true polymorphic behavior, C++ requires it be specified. However! It is only required to be specified in the base class, as all derived class will inherit the virtual member functions. If a member inherits a virtual member function, it is good practice to place 'virtual' in the declaration, but not required.
ADTs usually implement pure virtual functions to indicate that the derived classes MUST implement the function. Such as:
animal makeNoise() = 0; /*Indicates this function contains no implementation.
and must be implemented by derived classes in order to function.*/
Again, it is not required the derived classes include 'virtual' in their inherited members so long as the base class includes this.

If you want to deduce the type of the Animal and then call make_sound(), then you would have to do a dynamic_cast on the animal object for each and every child of animal. This would include any class that is directly or indirectly a child of the Animal class.
This is both difficult to maintain and very painful to any change eg. Adding new class as a child to the Animal class.
Since c++ philosophy is efficiency, you will have to ask the compiler to provide you with run-time polymorphism as it is costly. How would you do that? By stating the make_sound() function as virtual. This creates a vtable ( a table of functions pointers ) which refers to an address of make_sound() which differs to based on the type of the object.
No need to downcast as indirection handles everything for you. What could be hundreds of lines of code is just a single line of code. That is the power of indirection!!

You could say that you have to do it because that's one of the rules of the language.
There's a reason its helpful though.
When trying to validate the code that uses an Animal, the complier knows what functions exist on an Animal. Its possible to tell whether the code is correct without checking all classes that derive from animal. So that code doesn't need to depend on all those derived classes. If you derive a new class from Animal but forget to implement the makeNoise function that's an error in the new class not the code that uses the Animal base class and the complier can point you towards that error. Without the virtual function declared in Animal there would no way to tell if its the calling code or the new class that is in error.
A key point here is that these errors would be caught at compile-time for C++ because of its static typing. Other languages can allow dynamic typing, which can make some things easier but, the errors would only be spotted at runtime.

In Java, all functions are virtual by default. In C++ they are not, so when you call a non-virtual function on a pointer of a given type, that type's implementation of that function is invoked with the object's address as this.
class Animal {
public:
void sound() { std::cout << "splat\n"; }
virtual void appearance() { std::cout << "animaly\n"; }
};
class Cat {
public:
void sound() { std::cout << "meow\n"; }
virtual void appearance() { std::cout << "furry\n"; }
};
int main() {
Animal a;
Cat c;
Animal* ac = new Cat;
a.sound(); // splat
a.appearance(); // animaly
c.sound(); // meow
c.appearance(); // furry
ac->sound(); // splat
ac->appearance(); // furry
}
This would occur when you wanted to write a function that generalized on "Animal" rather than requiring a specific derived class pointer.

In java you use virtual methods too.
It improves the loosely coupling of your software.
For example, you can use a library and don't know which animal they use internally. There is a animal implementation you don't know and you can use it because it's an animal. You get the animal with a library.getAnimal method. Now you can use their animal without to know which noise it makes, because they have to implement the method makeNoise.
Edit: So to answer your question, c++ wants a explicit declaration and in java it is implicit. so yes it is a kind of language specific idiosyncracy.

Related

C++ Conceptual Question: Why can't I use a partially finished abstract class?

I'am working on an abstract class, which later will be derived by several subclasses. However, pretty much of the functionality is non-abstract - so why can't I allocate an object of this abstract class and work with it, as long as I don't call any of the pure virtual functions? After all, the size of the abstract class is well known at compile time!?
The definition of abstract class is as:
Defines an abstract type which cannot be instantiated, but can be used as a base class.
From: https://en.cppreference.com/w/cpp/language/abstract_class
To use it in another way would go against the use of abstract classes.
Abstract classes are used to represent general concepts (for example, Shape, Animal), which can be used as base classes for concrete classes (for example, Circle, Dog).
No objects of an abstract class can be created (except for base subobjects of a class derived from it) and no non-static data members of an abstract class can be declared.
See also https://timsong-cpp.github.io/cppwp/n3337/class.abstract
as long as I don't call any of the pure virtual functions?
Except in trivial cases, this can be impossible to prove. Let's look at an example. Suppose this is your abstract class
class Abby { virtual void fun() const = 0; };
and suppose you are able to create an Abby object for testing.
// First source file
Abby test;
In a trivial case, you literally do nothing with this object except cast it to void to avoid a compiler warning about an unused variable. In a non-trivial case, you might pass this object (by reference) to a function defined in a different file than the one where the object is created, perhaps the following function.
// Second source file
void foo(const Abby & o)
{
o.fun();
}
This function expects an object that has Abby as a base class, and calls that object's virtual function. This works as long as it is forbidden to create an Abby object directly. If you relax this restriction, what happens? Should the compiler flag foo() as potentially broken because of what you might do in another translation unit? Should the compiler ignore the situation, leading to a runtime error?
Or maybe you would want a call to foo(test) to be flagged as making the definition of test to be invalid? This would be rather strange, to have the validity of one line (Abby test;) be dependent on what comes after it. It would also greatly limit what you could do in your test, leading compilers to ask why they bother. There is so little benefit to bending the rules this way, so why make a complicated language even more complicated?
Besides, it does not take much programming work to get the result you are looking for. Just comment out the pure virtual function.
class Abby { /* virtual void fun() const = 0; */ };
Since you're not calling it, this should not affect your code, right? If it does you could instead dummy-up the function, as in
class Abby { virtual void fun() const {} };
Revert this change once you are done testing.
Personally I might derive a class from Abby with a dummy fun() member, and use that concrete class for testing instead of the abstract class. However, the OP called that "a nuisance" in a comment.
class Concrete : public Abby { void fun() const override {} };

Is-a relationship without virtual functions c++

I couldn't find examples of is-a relationship without virtual functions. Is a following pattern ok?
class Base {
public:
void doSomethingWithX() {/*implementation here*/}
protected:
~Base(){}
private:
int x_;
};
class Derived : public Base {
//Add some other functionality but inherit doSomethingWithX and its implementaion
public:
void doSomethingWithY();
~Derived(); //And document that nobody should inherit further from this class.
private:
int y_;
};
foo(Base* ptr) {
//Do something via Base interface
}
Derived d;
foo(&d);
Edit: I was asked to clarify what I mean by "is this pattern ok".
Does this kind of inheritance satisfies what is usually needed from is-a relationship? Liskov substitution principle etc.
Is it safe to use Derived objects via pointer to Base? (or I miss some problem here).
I'm asking this because there is often written that base class destructor should be either public and virtual or protected and non-virtual. But I never met real examples of public inheritance without non-virtual functions.
It's okay for what you're doing here; You can pass a pointer to Derived and it can bind to a pointer of Base just fine. It's not possible to say whether it satisfies the Liskov subtitution principle because we do not know the invariants of your classes.
Just recognize that without any virtual functions, you cannot use polymorphism. This goes beyond simply overriding function behavior; you'll never be able to perform a dynamic_cast of a pointer to Base to a pointer to Derived.
Additionally, if nobody should derive from Derived, then mark it final, which is available since C++11
There are two types of polymorphism, both implementable in C++: static and dynamic. The latter is what you get with virtual functions and pointers to base classes, in which the behaviour is specialized depending on the real type of object pointed to.
The former can be achieved by writing a template, in which your template type is assumed to have certain interfaces. The compiler will then enforce that when instantiating the template, at compile time. You can provide additional enforcement using SFINAE and/or static_asserts to ensure the type used "is a" or rather conforms to the templated interface used by your code. Note there is not really a straightforward way of defining this interface as with a base interface class, aside from the aforementioned methods.
Note that static polymorphism is what you get at compile time. No dynamically chosen types at runtime. You'll need some form of base class for that.

virtual function and derived class

Let me show you the simple C++ code example first.
#include <iostream>
using namespace std;
class Person{
string m_name;
public:
virtual void saySomething(){
cout << "I am a person.";
}
};
class Student:public Person{
public:
void saySomething(){
cout << "I am a student." << endl;
}
};
class CSStudent:public Student{
public:
void saySomething(){
cout << "I am a CS Student." << endl;
}
};
int main(){
Person* p = new Person();
Student* s = new Student();
CSStudent* c = new CSStudent();
((Student*)c)->saySomething();
return 0;
}
In my example, Student is a derived class of Person.
Also, CSStudent is a derived class of Student.
I know virtual keyword make it possible to determine if it is derived class.
Question 1.
((Student*)c)->saySomething();
Why do I get "I am a CS Student."?
I expected "I am a Student." since I specify virtual keyword only for the Person.
Question 2.
I saw an example that puts a virtual keyword to only base case.
Also, I saw an example that puts virtual keywords to all base case and derived classes. What's the difference between these two?
Question 3.
virtual function is determined in run time.
What about non-virtual function? Is it determined in compile time?
For the first question, even if you cast c to another class based on the same base-class, it's still the original class (i.e. CSStudent). Virtual functions are (almost always) implemented through a jump table. So the c object have a table which contains the address to the actual function in the c object. This table will not change because you re-cast the type.
For the second question, there is no difference. If you mark a member function as virtual in the base class, it will be virtual in all child-classes as well. It's just that some people prefer to mark the functions in the child-classes virtual too. It can actually be good because then you don't have to check the base-class to see which functions are virtual and which are not.
And for the third question. Yes, virtual functions are calculated runtime using the table as described above, while non-virtual functions are determined at compilation time.
Question 1.
((Student*)c)->saySomething();
Why do I get "I am a CS Student."? I expected "I am a Student." since I specify virtual keyword only for the Person.
In C++, if the base class specifies that a function is virtual, then you don't need the virtual keyword in any derived classes for member functions with the same signature. You can include it if you want to (and it's generally good practice to do so), but it's optional.
Question 2.
I saw some example on the web page that mentions virtual keyword to only base case. Also, I saw some example that mentions virtual keyword to all base case and derived classes. What's the difference between these two?
As above: there is no difference. If the base class says a method with a particular signature is virtual, then that applies to all derived classes too.
Question 3.
virtual function is determined in run time. What about non-virtual function? Is it determined in compile time?
Yes. If your saySomething() function was non-virtual, then the calls would be resolved at compile-time, and the cast to Student* would mean you'd get the Student version of saySomething().
Why do I get "I am a CS Student."? I expected "I am a Student." since
I specify virtual keyword only for the Person.
In C++, if you specify the virtual keyword in a base class, that method will automatically be made virtual in any subclasses as well. (I won't try to speculate on why C++ works that way, but it does)
I saw an example that puts a virtual keyword to only base case. Also, I saw an example that puts virtual keywords to all base case and derived classes. What's the difference between these two?
Functionally there is no difference. I think stylistically the latter one is a little better in terms of being self-documenting.
virtual function is determined in run time. What about non-virtual
function? Is it determined in compile time?
Correct. In particular, the method implementation that gets called for a non-virtual method will be determined solely by the pointer type it was called through, rather than via dynamic lookup of the appropriate subclass method.

Why do we need abstract classes in C++?

I've just learned about polymorphism in my OOP Class and I'm having a hard time understanding how abstract base classes are useful.
What is the purpose of an abstract class? What does defining an abstract base class provide that isn't provided by creating each necessary function in each actual class?
The purpose of an abstract class is to define a common protocol for a set of concrete subclasses. This is useful when defining objects that share code, abstract ideas, etc.
Abstract classes have no instances. An abstract class must have at least one deferred method (or function). To accomplish this in C++, a pure virtual member function is declared but not defined in the abstract class:
class MyClass {
virtual void pureVirtualFunction() = 0;
}
Attempts to instantiate an abstract class will always result in a compiler error.
"What does defining an abstract base class provide that isn't provided
by creating each necessary function in each actual class?"
The main idea here is code reuse and proper partitioning across classes. It makes more sense to define a function once in a parent class rather than defining over and over again in multiple subclasses:
class A {
void func1();
virtual void func2() = 0;
}
class B : public A {
// inherits A's func1()
virtual void func2(); // Function defined in implementation file
}
class C : public A {
// inherits A's func1()
virtual void func2(); // Function defined in implementation file
}
Having an abstract class like "Dog" with a virtual method like "bark" allows all classes that inherit from Dog to have their bark code called in the same way, even though the Beagle's bark is implemented way differently than the Collie's.
Without a common abstract parent (or at least a common parent with a bark virtual method) it'd be difficult to do the following:
Have a Vector of type Dog that contains Collies, Beagles, German Shepherds etc and make each of them bark. With a Vector of Dogs that contains Collies, Beagles, German Shepherds all you would have to do to make them all bark is to iterate through in a for loop and call bark on each one. Otherwise you'd have to have a separate Vector of Collies, Vector of Beagles etc.
If the question is "why make Dog abstract when it could be concrete, have a virtual bark defined with a default implementation that can be overriden?", the answer would be that this may be acceptable sometimes -- but, from a design perspective, there really isn't any such thing as a Dog that isn't a Collie or a Beagle or some other breed or mix so although they are all Dogs, there is not one of them in reality that is a Dog but not some other derived class too. Also, since dogs barking is so varied from one breed to another, there is unlikely to be any real acceptable default implementation of bark that would be acceptable for any decent group of Dogs.
I hope this helps you understand the purpose: yes, you're going to have to implement bark in each subclass anyway, but the common abstract ancestor lets you treat any subclass as a member of a base class and invoke behaviors that may be conceptually similar like bark but in fact have very different implementations.
Abstract classes allow for compile time protocol enforcement. These protocols define what it means to be a part of a class family.
Another way to think of it is that a abstract class is a contract that your implementing classes must fulfill. If they do not fulfill this contract they cannot be part of the class family and they must be modified to conform to the contract. The provided contract may provide default functionality, but it also leaves it up to the sub-class to define more specific or different functionality while still remaining within the scope of the contract.
For small projects this may not seem useful but for large projects it provides conformity and structure as it provides documentation through the abstract class contract. This makes for more maintainable code and makes for the sub-classes to each have the same protocol making using and developing new sub-classes easier.
The purpose of an abstract class is to provide an appropriate base class from which other classes can inherit. Abstract classes cannot be used to instantiate objects and serves only as an interface. Attempting to instantiate an object of an abstract class causes a compilation error. (because vtable entry is not filled with memory location for virtual function we mentioned in Abstract Class)
Thus, if a subclass of an ABC needs to be instantiated, it has to implement each of the virtual functions, which means that it supports the interface declared by the ABC. Failure to override a pure virtual function in a derived class, then attempting to instantiate objects of that class, is a compilation error.
Example:
class mobileinternet
{
public:
virtual enableinternet()=0;//defines as virtual so that each class can overwrite
};
class 2gplan : public mobileinternet
{
private:
int providelowspeedinternet(); //logic to give less speed.
public:
void enableinternet(int) {
// implement logic
}
};
//similarly
class 3gplan : public enableinternet
{
private: high speed logic (different then both of the above)
public:
/* */
}
here in this example, you can understand.
I have a dog. Abstract class dog with a method bark. My particular dog makes one bark. Other dogs bark in a different way. So defining a dog in the abstract way is useful.
Abstract classes are used to define an interface to be implemented. See some references:
http://en.wikibooks.org/wiki/C%2B%2B_Programming/Classes/Abstract_Classes
An abstract class AbstractClass as a base class is needed when there is functionality that is desired for all objects that have a type deriving from AbstractClass, but cannot sensibly be implemented on the AbstractClass itself.
The old and somewhat artificial OO example of having a base class Vehicle with derived classes Car, Motorcycle, ... provides a good example here, say you want a method move() - you can implement the way that a Car or a Motorcycle moves, but Vehicles don't move in a generic way, so Vehicle::move() will have to be pure virtual and Vehicle therefore abstract.
why don't we create each necessary function in each class ? (C++)
You have to create each necessary function marked as abstract in each derived class.
If you question is, why to create abstract function in abstract class?
It allows strict run time polymorphism.
Also read Interface vs Abstract Class (general OO)
abstract class dog
{
bark();
}
// function inside another module
dogbarking(dog obj)
{
dog.bark(); // function will call depend up on address inside the obj
}
// our class
ourclass: inherit dog
{
bark()
{
//body
}
}
main()
{
ourclass obj;
dogbarking(obj);
}
we can see that dogbarking is a function written in another module. it knows only the abstract class dog. even though it can call the function bark inside ourclass. in main function we create object of ourclass and pass to function dogbarking where it received using reference object of abstract class dog.
Imagine you have two methods for displaying a string:
DisplayDialog(string s);
PrintToConsole(string s);
And you want to write some code that can be switched between these two methods:
void foo(bool useDialogs) {
if (useDialogs) {
DisplayDialog("Hello, World!");
} else {
PrintToConsole("Hello, World!");
}
if (useDialogs) {
DisplayDialog("The result of 2 * 3 is ");
} else {
PrintToConsole("The result of 2 * 3 is ");
}
int i = 2 * 3;
string s = to_string(i);
if (useDialogs) {
DisplayDialog(s);
} else {
PrintToConsole(s);
}
}
This code is tightly coupled to the specific methods used for displaying the string. Adding an additional method, changing how the method is selected, etc. will affect every piece of code that uses this. This code is tightly coupled to the set of methods we use to display strings.
Abstract base classes are a way of decoupling code that uses some functionality from the code that implements that functionality. It does this by defining a common interface to all the various ways of doing the task.
class AbstractStringDisplayer {
public:
virtual display(string s) = 0;
virtual ~AbstractStringDisplayer();
};
void foo(AbstractStringDisplayer *asd) {
asd->display("Hello, World!");
asd->display("The result of 2 * 3 is ");
int i = 2 * 3;
string s = to_string(i);
asd->display(s);
}
int main() {
AbstractStringDisplayer *asd = getStringDisplayerBasedOnUserPreferencesOrWhatever();
foo(asd);
}
Using the interface defined by AbstractStringDisplayer we can create and use as many new ways of displaying strings as we want, and code that uses the abstract interface won't need to be changed.

Virtual difference syntax C++ [duplicate]

This question already has answers here:
Virtual/pure virtual explained
(12 answers)
Closed 8 years ago.
With C++, virtual is used like this? What's the difference between the both?
class Animal
{
public:
virtual void something();
virtual void something() = 0;
}
I might be fuzzy on this but I think the first says: You can override me, and the second says, You must override me.
virtual void something() = 0; // says it is a pure virtual function
virtual void something(); // is a virtual function
And classes that contain atleast one pure virtual function are called abstract base classes.The main difference between an abstract base class and a regular polymorphic class is that because in abstract base classes at least one of its members lacks implementation, we cannot create instances (objects) of it.
The first states that the function is virtual: that subclasses can override the behaviour. However, the function still has an implementation in the base class. The second is pure virtual: it doesn't have an implementation, and must be overridden by a subclass. It's similar to the abstract keyword in Java and C#. It makes the class abstract too, so it cannot be instantiated.
The second "something" must be implemented by subclasses and any class containing "xxx() = 0" cannot be directly instantiated. It's called a "pure virtual" function and classes containing them are "abstract". A class containing nothing but pure virtuals is "pure abstract".
first one is just declaring a virtual method. if you extend the class and override that method then the child class' implementation is called.
2nd one is a pure virtual method. in other words neither your class or any class that extends it be instantiated (abstract) without first providing a definition for something().
Consider:
class Sloth : public Animal { void something() { ... } };
Animal animal;
Sloth sloth;
Here, we're trying to create two objects - an Animal and a Sloth. But, should we be allowed to create an animal? Perhaps the programmer has created Animal just so it can be used to refer polymorphically to derived types, as in:
std::vector<Animal*> zoo;
zoo.push_back(new Sloth());
zoo.push_back(new Sea_Eagle());
They might then expect p_animal->something() to do something useful. Given Animal is only inteded for this polymorphic abstraction, it would be wrong for anyone to put an actual "new Animal()" object directly into the zoo (or operate on one anywhere else in the program).
Say it was possible - what should then happen if a programmer using this Animal class creates an instance and calls the something() function? Perhaps nothing, or perhaps it's an error condition and should never appear in good code - rather than having Animal's something() function print an error message or throws an exception at run time. That's ugly - run-time errors mean the program is failing when the client's trying to use it.
C++ supports the "= 0" notation so that the compiler knows to prevent (base-class) Animal objects being created at compile time, so you can ship software that always works for the user.