Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface and virtual functions in C++ compared to Java interface

I have a question regarding C++ virtual functions. The virtual keyword is used in C++ class declaration on a function in a base class in order to notify that a sub-class implementation of that function may differ from sub-class to sub-class. Different sub-classes may have different implementations of the function.

I don't get it a bit. When you define interface in C++ it is not like in Java as far as I can see by now.

In fact I don't understand what the word interface in C++ means. You specify a function as virtual in the header file. Then sub-classes or derived classes of base class can override it in any way you want as long it is a virtual function.

Is the interface in C++ a header file?

Cheers

like image 667
uml Avatar asked Dec 01 '22 04:12

uml


2 Answers

Interface in Java is a particular language construct or keyword. Java has a keyword interface that is used to indicate that a Java class does not provide the actual implementation but instead describes the interface that a derived class must implement. This is checked by the Java compiler to ensure that a class that claims to implement an interface provides all the necessary methods for the interface.

In Java the interface key word indicates that a class provides a set of services described by the interface class specified. A Java class may implement multiple different interfaces.

The way that the word interface is used in discussions with C++ is a somewhat similar concept since it has to do with the parameter types of a class or function or method. However there is no interface keyword in C++. The word interface is used in a more generic, descriptive way with C++ as in "The function interface takes two shorts and a long." which is indicating the function calling arguments and their types, the interface between the caller of the function and the function body.

So think of interface in C++ as a kind of contract between the class implementing the interface and any objects that are using objects instantiated from the class. A class can also actually provide several different related services each of which has a particular interface.

One can do something similar to the Java interface concept in C++ by using pure virtual methods in a class description to create an abstract class. This creates a C++ class with no implementation. See C++: Create abstract class with abstract method and override the method in a subclass.

What a virtual method does is to provide a mechanism so that objects using derived classes of the class can depend on a particular interface while leaving the details of the implementation to the derived class. So this is similar to the Java interface. C++ virtual methods is a way to provide a way to implement a Java interface using a compiled and static checked approach rather than a run time approach.

With a virtual method you create a super class type that can be used to create pointer variables that can be assigned variables from the derived types and when you use the virtual method, the correct method from the derived class will be called. Figuring out which method to call is done at compile time not run time. The major idea for C++ is to be as efficient as C while providing object oriented language constructs along with static type checking at compile time to reduce reliance on error detect at run time with its additional overhead.

class Joe {
public:
virtual int thingOne() { return 1;}  // standard, not pure virtual method
..
};

class JoeTwo : public Joe {
public:
int thingOne() { return 2;}   // derived class provides its own version of the method
..
};

Joe *myJoe = new JoeTwo;

int i = myJoe->thingOne();  // value of 2 put into i and not value of 1

With C++ you do need to recognize the difference between an object and a pointer to an object because of object slicing which can happen when a variable containing a derived object is assigned to a variable containing the derived object's super class. This "object slicing" will happen because the derived object does not fit into the base class or super class object from which it is derived. The derived object has additional stuff the super class object does not have so with the assignment (default assignment is straight memory copy) only the super class part of the derived object is copied into the super class object.

class Joe {
public:
virtual int thingOne() { return 1;}  // standard, not pure virtual method
..
};

class JoeTwo : public Joe {
public:
int thingOne() { return 2;}   // derived class provides its own version of the method
..
};

Joe *myJoe = new JoeTwo;    // no object slicing since this is pointer
JoeTwo myJoeTwo;
Joe  myJoeSliced = myJoeTwo;  // JoeTwo object myJoeTwo sliced to fit into Joe object myJoeSliced
like image 56
Richard Chambers Avatar answered Dec 02 '22 16:12

Richard Chambers


The main difference between Java and C++ is the fact that in Java every function is virtual.

Historically when C++ have been developed the fact of placing an abastraction layer between every function call (that is what happens using a virtual method table) wasn't something you did want for every method call because a virtual method invocation is slower.

So what happens is that you must specify that a method must be called through dynamic binding, otherwise the method is chosen during compile time according to the declaration of the variable. This means that if you declare Base *b = new Derived() and you call a method on b which is not virtual then method is chosen at compile time and it will be a Base::method.

The motto is you don't pay for what you don't use and that's it.

Interfaces in C++ doesn't exist, but you can have a class with just pure virtual functions which behave basically in the same way. Actually you can have two kind of virtual methods:

class Base {
  virtual void method() {
    //implementation
  }
  virtual void pureMethod() = 0;
}

First method() is virtual and obeys to dynamic binding but it is implemented even in Base class while pureMethod() still obeys to dynamic binding but it's declared as pure virtual so it doesn't have any implementation, thus Base cannot be instantiated as it is and you need to subclass it and override at least the pure virtual method.

like image 25
Jack Avatar answered Dec 02 '22 17:12

Jack