usage of virtual keyword with a class declaration - c++

I was asked in an interview that what is the usage of virtual keyword with a class declaration in C++ and I answered that virtual keyword cannot be used with a class declaration in C++. The interviewer said that it is possible and asked me to test it later.
Now that I have checked it myself I have come to know that this is possible and this is not a compiler error. In fact, when I do something like this with a Visual C++ compiler:
virtual class Test
{
int i;
};
I get a compiler warning "warning C4091: 'virtual ' : ignored on left of 'Test' when no variable is declared". I haven't been able to find out yet that what this warning means and further what is the usage of virtual keyword. If there is no helpful usage, then why is this allowed in the first place and why is this not a compiler error.

That's a bug in VC++. Comeau and gcc both reject the code.

virtual can be used when deriving from another class:
class Foo : public virtual Bar
{
}
This is used to avoid having multiple versions of the same base class when using multiple inheritance. Wikipedia has a good article on the subject.

You simply can't use virtual for a class. It only works for member functions

You're looking at the wrong sort of usage - I'm pretty sure that the interviewer was referring to virtual base class declarations, like so:
class A : virtual public B, public C {
...
};
This is a common idiom and used to get around the "multiple base class" scenario in diamond-shaped inheritance trees. The typical problem with them is that you inherit from both class B and class C and they share the common ancestor A. If you go 'up' the inheritance tree you'll hit the ambiguity as to which instance of 'A' you're supposed to use. If B & C have A as a virtual base class instead, they will refer to the same instance of A, which solves this problem.
You can find a more exhaustive description with class diagrams here.

Maybe he was referring to virtual inheritance / virtual base classes? E.g.
class A : virtual public B
{ ... }
That would technically be part of the class definition.

Could he have been talking about using a virtual base class in the class declaration?
Like this:
class CashierQueue : virtual public Queue {};
This is used in multiple inheritance when you want to avoid a derived class having multiple copies of the member data when it inherits from two or more classes that share the same base class.
class Queue {};
class CashierQueue : virtual public Queue {};
class LunchQueue : virtual public Queue {};
class LunchCashierQueue : public LunchQueue, public CashierQueue {};
See http://msdn.microsoft.com/en-us/library/wcz57btd(VS.80).aspx

Related

Can a C++ class without any pure virtual methods be considered abstract?

My understanding is that abstract classes must have one or more pure virtual methods.
Can this class be considered abstract?
class B {
protected:
B() { }
public:
virtual ~B() { }
};
Finally, is the term abstract class defined in any of the recent C++ standards?
No, such a class cannot be considered abstract because (as mentioned in the comments, excerpt from the working draft):
A class is abstract if it has at least one pure virtual function.
Unfortunately, there are cases when one cannot add a pure virtual method to a class to turn it in an abstract one and still he doesn't want users to be able to instantiate that class.
For the sake of curiosity, I'm adding this answer to mention an often unknown technique to work around the issue.
Actually, you can easily turn such a class in an abstract one, even if you don't have any virtual method to be added to it.
The basic idea is to exploit the destructor declaration to do that.
A minimal, (not) working example follows:
struct B { virtual ~B() = 0; };
// keep in mind the ODR
B::~B() { }
int main() { B b{}; }
The code above won't compile with the error:
cannot declare variable 'b' to be of abstract type 'B'
Please, note that the definition of the destructor should be placed in a .cpp file, so as not to violate the ODR.
To be honest, I haven't found any case in which this technique can be used till now. Anyway, it's worth mentioning it for future readers.
abstract classes must have one or more pure virtual methods.
Exactly, and you class don't have it.
In accordance with this, a abstract class is a type which cannot be instantiated, but can be used as a base class (note: not "by"). In C++ this can be achieved with the usage of pure virtual method.
A pure virtual method is a virtual function whose declarator has the following syntax:
class B {
virtual void foo() = 0;
}
Note: the syntax = 0 which indicates a pure virtual method. That simply means you don't have to specify an implementation for that method, and it cannot be possible to create any instance of that class (that is, a abstract class).
In conclusion your class B is not an abstract class.
Finally, is the term abstract class defined in any of the recent C++ standards?
The abstract class is a definition itself, and it's define as I've just mentioned before.
If you mean a specific defined syntax as, for example in Java (abstract class ...), then the answer is no. Again an abstract class in C++ is defined just with a class which has a pure virtual method.
No, class B can not be considered as abstract.
class A {
public:
virtual void method() = 0;
virtual ~A() = 0;
}
A is pure virtual, you cannot create object of A. You must create children class B which implements method after A.

More methods in derived classes than base class

I would like to ask a question about programming style in this case of derived class:
class A
{
public:
virtual foo1()=0;
}
class B: public A
{
public:
virtual foo1();
virtual foo2();
}
class C: public A
{
public:
virtual foo1();
}
int main() {
B mB();
C mC();
mB.foo2() //OK!
mC.foo2() // obviously, it is not correct
return 0;}
Therefore, should a derived class have less or equal public methods than the abstract base class?
If the derived classes require more methods, should these be private?
Derived classes will almost always have more public functions than base classes. This is the point of inheritance: you can define an abstract base class which only outlines the basic behavior of a variable, then derived classes can expand upon this basic behavior for specific cases.
An inherited class is always a specialization of the base class. It implements more specific functions (and usually more functions all together). In you're example, you're expecting two different specializations to behave the same way outside of the behavior defined by the base class. (foo2 is not defined in A). That's where the problem lies. If you need to define common behavior outside of A, the solution would be to create an intermediate class.
class Intermediate : public A
{
public:
virtual foo1()=0;
virtual foo2()=0;
}
class B: public Intermediate
{
public:
virtual foo1();
virtual foo2();
}
Now any class which can implement foo2 should extend Intermediate, and any function which requires functionality foo2 should ask for a variable with at least type Intermediate.
There is nothing wrong with this class structure. There is nothing wrong with a derived class having more methods than the parent class-- it's quite commonplace. The line mC.foo2(); is just wrong, and that is not the fault of the classes.
A derived class must at least implement ALL abstract methods from the base class. This is the minimum. If you do add other methods, members or whatever is up to you.
But it would be not very smart to derive from the class and add nothing, because this is not what inheritance is for (at least IS-A-relationships). If you go for private inheritance it might be different.
In nearly ALL projects I've worked on, we have had baseclasses that have less functionality than the derived class - in extreme cases, the baseclass may even just have nearly no functionality, but the derived class has dozens of functions and a half a dozen member variables.
This is exactly what derived classes are meant to do.
Obviously, you need to KNOW what kind of derived class you have, and only use the derived classes "extra" functions when they are available.

Ambiguity in multiple inheritance of interfaces in C++

I made a test code as following:
#include <iostream>
using namespace std;
#ifndef interface
#define interface struct
#endif
interface Base
{
virtual void funcBase() = 0;
};
interface Derived1 : public Base
{
virtual void funcDerived1() = 0;
};
interface Derived2 : public Base
{
virtual void funcDerived2() = 0;
};
interface DDerived : public Derived1, public Derived2
{
virtual void funcDDerived() = 0;
};
class Implementation : public DDerived
{
public:
void funcBase() { cout << "base" << endl; }
void funcDerived1() { cout << "derived1" << endl; }
void funcDerived2() { cout << "derived2" << endl; }
void funcDDerived() { cout << "dderived" << endl; }
};
int main()
{
DDerived *pObject = new Implementation;
pObject->funcBase();
return 0;
}
The reason I wrote this code is to test if the function funcBase() can be called in an instance of DDerived or not. My C++ complier (Visual Studio 2010) gave me a compile error message when I tried to compile this code. In my opinion, there is no problem in this code because it is certain that the function funcBase() will be implemented (thus overriden) in some derived class of the interface DDerived, because it is pure virtual. In other words, any pointer variable of type Implementation * should be associated with an instance of a class deriving Implentation and overriding the function funcBase().
My question is, why the compiler give me such an error message? Why the C++ syntax is defined like that; i.e., to treat this case as an error? How can I make the code runs? I want to allow multiple inheritance of interfaces. Of course, if I use "virtual public" or re-declare the function funcBase() in Implementation like
interface DDerived : public Derived1, public Derived2
{
virtual void funcBase() = 0;
virtual void funcDDerived() = 0;
};
then everything runs with no problem.
But I don't want to do that and looking for more convenient method, because virtual inheritance may degrade the performance, and re-declaration is so tedious to do if inheritance relations of classes are very complex. Is there any methods to enable multiple inheritance of interfaces in C++ other than using virtual inheritance?
As you've defined it, your object structure looks like this:
The important point here is that each instance of Implementation contains two entirely separate instances of Base. You're providing an override of Base::funcBase, but it doesn't know whether you're trying to override funcBase for the Base you inherited through Derived1, or the Base you inherited through Derived2.
Yes, the clean way to deal with this is virtual inheritance. This will change your structure so there's only one instance of Base:
This is almost undoubtedly what you really want. Yes, it got a reputation for performance problems in the days of primitive compilers and 25 MHz 486's and such. With a modern compiler and processor, you're unlikely to encounter a problem.
Another possibility would be some sort of template-based alternative, but that tends to pervade the rest of your code -- i.e., instead of passing a Base *, you write a template that will work with anything that provides functions A, B, and C, then pass (the equivalent of) Implementation as a template parameter.
The C++ language is designed in such a way that in your first approach without virtual inheritance there will be two parent copies of the method and it can't figure out which one to call.
Virtual inheritance is the C++ solution to inheriting the same function from multiple bases, so I would suggest just using that approach.
Alternately have you considered just not inheriting the same function from multiple bases? Do you really have a derived class that you need to be able to treat as Derived1 or Derived2 OR Base depending on the context?
In this case elaborating on a concrete problem rather than a contrived example may help provide a better design.
DDerived *pObject = new Implementation;
pObject->funcBase();
This creates a pointer of type DDerived to a Implementation. When you are using DDerived you really just have a pointer to an interface.
DDerived does not know about the implementation of funcBase because of the ambiguity of having funcBase being defined in both Derived1 and Derived2.
This has created a inheritance diamond which is what is really causing the problem.
http://en.wikipedia.org/wiki/Diamond_problem
I also had to check on the interface "keyword" you have in there
it's an ms-specific extension that's recognised by visual studio
I think C++ Standard 10.1.4 - 10.1.5 can help you to understand the problem in your code.
class L { public: int next; /∗ ... ∗/ };
class A : public L { /∗...∗/ };
class B : public L { /∗...∗/ };
class C : public A, public B { void f(); /∗ ... ∗/ };
10.1.4 A base class specifier that does not contain the keyword virtual,
specifies a non-virtual base class. A base class specifier that
contains the keyword virtual, specifies a virtual base class. For each
distinct occurrence of a non-virtual base class in the class lattice
of the most derived class, the most derived object (1.8) shall contain
a corresponding distinct base class subobject of that type. For each
distinct base class that is specified virtual, the most derived object
shall contain a single base class subobject of that type. [ Example:
for an object of class type C, each distinct occurrence of a
(non-virtual) base class L in the class lattice of C corresponds
one-to-one with a distinct L subobject within the object of type C.
Given the class C defined above, an object of class C will have two
subobjects of class L as shown below.
10.1.5 In such lattices, explicit qualification can be used to specify which
subobject is meant. The body of function C::f could refer to the
member next of each L subobject: void C::f() { A::next = B::next; } //
well-formed. Without the A:: or B:: qualifiers, the definition of C::f
above would be ill-formed because of ambiguity
So just add qualifiers when calling pObject->funcBase() or solve ambiguity in another way.
pObject->Derived1::funcBase();
Updated: Also very helpful reading will be 10.3 Virtual Functions of Standard.
Have a nice weekend :)

Virtual Inheritance Confusion

I'm reading about inheritance and I have a major issue that I haven't been able to solve for hours:
Given a class Bar is a class with virtual functions,
class Bar
{
virtual void Cook();
};
What is the different between:
class Foo : public Bar
{
virtual void Cook();
};
and
class Foo : public virtual Bar
{
virtual void Cook();
};
? Hours of Googling and reading came up with lots of information about its uses, but none actually tell me what the difference between the two are, and just confuse me more.
Functionality wise there is not much difference between the 2 versions. With the case of virtual inheritance, every implementation generally adds a (vptr like) pointer (same as in the case of virtual functions). Which helps to avoid multiple base class copies generated due to multiple inheritance (the diamond inheritance problem)
Also, virtual inheritance delegates the right to call the constructor of its base class. For example,
class Bar;
class Foo : public virtual Bar
class Other : public Foo // <--- one more level child class
So, now Bar::Bar() will be called directly from Other::Other() and also will be placed at the first place among other base classes.
This delegation feature helps in implementing a final class (in Java) functionality in C++03:
class Final {
Final() {}
friend class LastClass;
};
class LastClass : virtual Final { // <--- 'LastClass' is not derivable
...
};
class Child : public LastClass { // <--- not possible to have object of 'Child'
};
Virtual inheritance is only relevant if classes are to inherit from
Foo. If I define the following:
class B {};
class L : virtual public B {};
class R : virtual public B {};
class D : public L, public R {};
Then the final object will only contain one copy of B, shared by both
L and R. Without the virtual, an object of type D would contain
two copies of B, one in L, and one in R.
There is some argument that all inheritance should be virtual (because
in the cases where it makes a difference, that is what you want most of
the time). In practice, however, virtual inheritance is expensive, and
in most cases, not necessary: in a well designed system, most
inheritance will simply be of a concrete class inheriting from one or
more "interfaces"; such a concrete class is usually not designed to be
derived from itself, so there is no problem. But there are important
exceptions: if, for example, you define an interface, and then
extensions to the interface, the extensions should inherit virtually
from the base interface, since a concrete implementation could want to
implement several extensions. Or if you are designing mixins, where
certain classes only implement part of the interface, and the final
class inherits from several of these classes (one per part of the
interface). In the end, the criteron as to whether to inherit virtually
or not isn't too difficult:
if the inheritance isn't public, it probably shouldn't be virtual
(I've never seen an exception), otherwise
if the class is not designed to be a base class, there's no need for
virtual inheritance, otherwise
the inheritance should be virtual.
There are a few exceptions, but the above rules err on the side of
safety; it's usually "correct" to inherit virtually even in cases where
the virtual inheritance isn't necessary.
One final point: a virtual base must always be initialized by the most
derived class, not the class that directly inherits (and declares that
the inheritance is virtual). In practice, however, this is a non-issue.
If you look at the cases where virtual inheritance makes sense, it is
always a case of inheriting from an interface, which will contain no
data, and thus have (only) a default constructor. If you find yourself
inheriting virtually from classes with constructors which take
arguments, it's time to ask some serious questions about the design.
In this case, no difference. Virtual inheritance is related to sharing superclass subobjects instances by derived classes
struct A
{
int a;
};
struct B : public virtual A
{
int b;
}
struct C : public virtual A
{
int c;
};
struct D : public B, public C
{
};
There's a single copy of the member variable a in the instance of D; If A was not a virtual base class, there would be two A subobjects in instance of D.
Virtual function is a function that will probably have different implementation in derived class (although it's not a must).
In your last example is virtual inheritance. Imagine a case where you have two classes (A and B) derived from a base class (let's call it 'Base'). Now imagine a third class C derived from A and B. Without virtual inheritance, the C would contain two copies of 'Base'. That could lead to ambiguity while compiling. The important thing in virtual inheritance is that the parameters for the 'Base' class constructor (if any) MUST be provided in the class C, because such calls from A and B will be ignored.

Using C++, how do I correctly inherit from the same base class twice?

This is our ideal inheritance hierarchy:
class Foobar;
class FoobarClient : Foobar;
class FoobarServer : Foobar;
class WindowsFoobar : Foobar;
class UnixFoobar : Foobar;
class WindowsFoobarClient : WindowsFoobar, FoobarClient;
class WindowsFoobarServer : WindowsFoobar, FoobarServer;
class UnixFoobarClient : UnixFoobar, FoobarClient;
class UnixFoobarServer : UnixFoobar, FoobarServer;
This is because the our inheritance hierarchy would try to inherit from Foobar twice, and as such, the compiler would complain of ambiguous references on any members of Foobar.
Allow me to explain why I want such a complex model. This is because we want to have the same variable accessible from WindowsFoobar, UnixFoobar, FoobarClient, and FoobarServer. This wouldn't be a problem, only I'd like to use multiple inheritance with any combination of the above, so that I can use a server/client function on any platform, and also use a platform function on either client or server.
I can't help but feel this is a somewhat common issue with multiple inheritance... Am I approaching this problem from completely the wrong angle?
Update 1:
Also, consider that we could use #ifdef to get around this, however, this will tend to yield very ugly code like such:
CFoobar::CFoobar()
#if SYSAPI_WIN32
: m_someData(1234)
#endif
{
}
... yuck!
Update 2:
For those who want to read more into the background of this issue, I really suggest skimming over the appropriate mailing list thread. Thing start to get interesting around the 3rd post. Also there is a related code commit with which you can see the real life code in question here.
It would work, although you'd get two copies of the base Foobar class. To get a single copy, you'd need to use virtual inheritance. Read on multiple inheritance here.
class Foobar;
class FoobarClient : virtual public Foobar;
class FoobarServer : virtual public Foobar;
class WindowsFoobar : virtual public Foobar;
class UnixFoobar : virtual public Foobar;
However, there are many problems associated with multiple inheritance. If you really want to have the model presented, why not make FoobarClient and FoobarServer take a reference to Foobar at construction time, and then have Foobar& FoobarClient/Server::getFoobar ?
Composition is often a way out of multiple inheritance. Take a example now:
class WindowsFoobarClient : public WindowsFoobar
{
FoobarClient client;
public:
WindowsFoobarClient() : client( this ) {}
FoobarClient& getClient() { return client }
}
However care must be taken in using this in the constructor.
What you are directly after here is virtual inheritance feature of C++. What you are in here for is a maintenance nightmare. This might not be a huge surprise since well-known authors like H. Sutter have been arguing against such use of inheritance for a while already. But this comes from direct experience with code like this. Avoid deep inheritance chains. Be very afraid of the protected keyword - it's use is very limited. This kind of design quickly gets out of hand - tracking down patterns of access to protected variable somewhere up the inheritance chain from lower level classes becomes hard, responsibilities of the code parts become vague, etc., and people who look at your code a year from now will hate you :)
You're in C++, you should get friendly with templates. Using the template-argument-is-a-base-class pattern, you'll not need any multiple inheritance or redundant implementations. It will look like this:
class Foobar {};
template <typename Base> class UnixFoobarAspect : public Base {};
template <typename Base> class WindowsFoobarAspect : public Base {};
template <typename Base> class FoobarClientAspect : public Base {};
template <typename Base> class FoobarServerAspect : public Base {};
typedef UnixFoobarAspect<FoobarClientAspect<Foobar>/*this whitespace not needed in C++0x*/> UnixFoobarClient;
typedef WindowsFoobarAspect<FoobarClientAspect<Foobar> > WindowsFoobarClient;
typedef UnixFoobarAspect<FoobarServerAspect<Foobar> > UnixFoobarServer;
typedef WindowsFoobarAspect<FoobarServerAspect<Foobar> > WindowsFoobarServer;
You might also consider using the curiously recurring template pattern instead of declaring abstract functions to avoid virtual function calls when the base class needs to call a function implemented in one of the specialized variants.
Use virtual inheritance, in the declaration of FoobarClient, FoobarServer, WindowsFoobar and UnixFoobar, put the word virtual before the Foobar base class name.
This will ensure there is always a single instance of Foobar no matter how many times it appears in your base class hierarchy.
Have a look at this search. Diamond inheritance is somewhat of contentuous issue and the proper solution dependes on individual situation.
I would like to comment on the Unix/Windows side of things. Generally one would #ifndef things out that are not appropriate for the particular platform. So you would end up with just Foobar compiled for either Windows or Unix using preprocessor directives, not UnixFoobar and WindowsFoobar. See how far you can get using that paradigm before exploring virtual inheritance.
Try this example of composition and inheritance:
class Client_Base;
class Server_Base;
class Foobar
{
Client_Base * p_client;
Server_Base * p_server;
};
class Windows_Client : public Client_Base;
class Windows_Server : public Server_Base;
class Win32 : Foobar
{
Win32()
{
p_client = new Windows_Client;
p_server = new Windows_Server;
}
};
class Unix_Client : public Client_Base;
class Unix_Server : public Server_Base;
class Unix : Foobar
{
Unix()
{
p_client = new Unix_Client;
p_server = new Unix_Server;
}
};
Many experts have said that issues can be resolved with another level of indirection.
There is nothing "illegal" about having the same base class twice. The final child class will just (literally) have multiple copies of the base class as part of it (including each variable in the base class, etc). It may result in some ambiguous calls to that base classes' functions, though, which you might have to resolve manually. This doesn't sound like what you want.
Consider composition instead of inheritance.
Also, virtual inheritance is a way to fold together the same base class which appears twice. If it really is just about data sharing, though, composition might make more sense.
You can access the variable with the qualified class name, but I forget the exact syntax.
However, this is one of the bad cases of using multiple inheritance that can cause you many difficulties. Chances are that you don't want to have things this way.
It's much more likely you want to have foobar privately inherited, have each subclass own a foobar, have foobar be a pure virtual class, or have the derived class own the things it currently defines or even define foobar on its own.