Why doesn't C++ have virtual variables? - c++

This might have been asked a million times before or might be incredibly stupid but why is it not implemented?
class A
{
public:
A(){ a = 5;}
int a;
};
class B:public A
{
public:
B(){ a = 0.5;}
float a;
};
int main()
{
A * a = new B();
cout<<a->a;
getch();
return 0;
}
This code will access A::a. How do I access B::a?

To access B::a:
cout << static_cast<B*>(a)->a;
To explicitly access both A::a and B::a:
cout << static_cast<B*>(a)->A::a;
cout << static_cast<B*>(a)->B::a;
(dynamic_cast is sometimes better than static_cast, but it can't be used here because A and B are not polymorphic.)
As to why C++ doesn't have virtual variables: Virtual functions permit polymorphism; in other words, they let a classes of two different types be treated the same by calling code, with any differences in the internal behavior of those two classes being encapsulated within the virtual functions.
Virtual member variables wouldn't really make sense; there's no behavior to encapsulate with simply accessing a variable.
Also keep in mind that C++ is statically typed. Virtual functions let you change behavior at runtime; your example code is trying to change not only behavior but data types at runtime (A::a is int, B::a is float), and C++ doesn't work that way. If you need to accommodate different data types at runtime, you need to encapsulate those differences within virtual functions that hide the differences in data types. For example (demo code only; for real code, you'd overload operator<< instead):
class A
{
public:
A(){ a = 5;}
int a;
virtual void output_to(ostream& o) const { o << a; }
};
class B:public A
{
public:
B(){ a = 0.5;}
float a;
void output_to(ostream& o) const { o << a; }
};
Also keep in mind that making member variables public like this can break encapsulation and is generally frowned upon.

By not making data public, and accessing them through virtual functions.
Consider for a moment, how what you ask for would have to be implemented. Basically, it would force any access to any data member to go through a virtual function. Remember, you are accessing data through a pointer to an A object, and class A doesn't know what you've done in class B.
In other words, we could make accessing any data member anywhere much slower -- or you could write a virtual method. Guess which C++'s designers chose..

You can't do this and C++ does not support it because it breaks with fundamental C++ principles.
A float is a different type than an int, and name lookup as well as determining what conversions will be needed for a value assignment happens at compile time. However what is really named by a->a including its actual type would only be known at runtime.
You can use templates to parameterize class A
template<typename T>
class A
{
public:
// see also constructor initializer lists
A(T t){ a = t; }
T a;
};
Then you can pass the type, however only at compile time for the above mentioned principle's reason.
A<int> a(5);
A<float> b(5.5f);

(dynamic_cast<B*>(a))->a ?
Why do you need that after all? Are virtual functions not enought?

You can downcast your variable to access B::a.
Something like:
((B*)a)->a
I think it is the same in most OO programming languages. I can't think of any one implementing virtual variables concept...

You can create such effect like this:
#include <iostream>
class A {
public:
double value;
A() {}
virtual ~A() {}
virtual void doSomething() {}
};
class B : public A {
public:
void doSomething() {
A::value = 3.14;
}
};
int main() {
A* a = new B();
a->doSomething();
std::cout << a->value << std::endl;
delete a;
return 0;
}
In the example above you could say that the value of A has the same effect as a virtual variable should have.
Edit: This is the actual answer to your question, but seeing your code example I noticed that you're seeking for different types in the virtual variable. You could replace double value with an union like this:
union {
int intValue;
float floatValue;
} value
and acces it like:
a->value.intValue = 3;
assert(a->value.floatValue == 3);
Note, for speed reasons I would avoid this.

Because according to the C standard, the offset of a field within a class or struct is required to be a compile-time constant. This also applies to when accessing base class fields.
Your example wouldn't work with virtual getters either, as the override requires the same type signature. If that was necessary, your virtual getter would have to return at algebraic type and the receiving code would have to check at run-time if it was of the expected type.

Leaving aside the argument that virtual methods should be private, virtual methods are intended as an extra layer of encapsulation (encapsulating variations in behavior). Directly accessing fields goes against encapsulation to begin with so it would be a bit hypocritical to make virtual fields. And since fields don't define behavior they merely store data, there isn't really any behavior to be virtualized. The very fact that you have a public int or float is an anti-pattern.

This isn't supported by C++ because it violates the principles of encapsulation.
Your classes should expose and implement a public (possibly virtual) interface that tells class users nothing about the internal workings of your class. The interface should describe operations (and results) that the class can do at an abstract level, not as "set this variable to X".

Related

Can you prevent inherited private members being called through the parent at compile time?

If you have a feature rich class, possibly one you do not own/control, it is often the case where you want to add some functionality so deriving makes sense.
Occasionally you want to subtract as well, that is disallow some part of the base interface. The common idiom I have seen is to derive and make some member functions private and then not implement them. As follows:
class Base
{
public:
virtual void foo() {}
void goo() { this->foo(); }
};
class Derived : public Base
{
private:
void foo();
};
someplace else:
Base * b= new Derived;
and yet another place:
b->foo(); // Any way to prevent this at compile time?
b->goo(); // or this?
It seems that if the compilation doesn't know that it is derived, the best you can do is not implement and have it fail at runtime.
The issue arises when you have a library, that you can't change, that takes a pointer to base, and you can implement some of the methods, but not all. So part of the library is useful, but you run the risk of core dumping if you don't know at compile time which functions will call what.
To make it more difficult, others may inherit from you class and want to use the library, and they may add some of the functions you didn't.
Is there another way? in C++11? in C++14?
Let's analyze this, focused on two major points:
class Base
{
public:
virtual void foo() {} // This 1)
// ...
class Derived : public Base // and this 2)
In 1) you tell the world that every object of Base offers the method foo() publicly. This implies that when I have Base*b I can call b->foo() - and b->goo().
In 2) you tell the world that your class Derived publicly behaves like a Base. Thus the following is possible:
void call(Base *b) { b->foo(); }
int main() {
Derived *b = new Derived();
call(b);
delete b;
}
Hopefully you see that there is no way call(Base*) can know if b is a derived and thus it can't possibly decide at compile-time if calling foo wouldn't be legal.
There are two ways to handle this:
You could change the visibility of foo(). This is probably not what you want because other classes can derive from Base and someone wants to call foo afterall. Keep in mind that virtual methods can be private, so you should probably declare Base as
class Base
{
virtual void foo() {}
public:
void goo() { this->foo(); }
};
You can change Derived so that it inherits either protected or private from Base. This implies that nobody/only inheriting classes can "see" that Derived is a Base and a call to foo()/goo() is not allowed:
class Derived : private Base
{
private:
void foo() override;
// Friends of this class can see the Base aspect
// .... OR
// public: // this way
// void foo(); // would allow access to foo()
};
// Derived d; d.goo() // <-- illegal
// d.foo() // <-- illegal because `private Base` is invisible
You should generally go with the latter because it doesn't involve changing the interface of the Base class - the "real" utility.
TL;DR: Deriving a class is a contract to provide at least that interface. Subtraction is not possible.
This seems to be what you want to do:
struct Library {
int balance();
virtual int giveth(); // overrideable
int taketh(); // part of the library
};
/* compiled into the library's object code: */
int Library::balance() { return giveth() - taketh(); }
/* Back in header files */
// PSEUDO CODE
struct IHaveABadFeelingAboutThis : public Library {
int giveth() override; // my implementation of this
int taketh() = delete; // NO TAKE!
};
So that you can't call taketh() on an IHaveABadFeelingAboutThis even when it is cast as the base class.
int main() {
IHaveABadFeelingAboutThis x;
Library* lib = &x;
lib->taketh(); // Compile error: NO TAKE CANDLE!
// but how should this be handled?
lib->balance();
}
If you want to present a different interface than the underlying library you need a facade to present your interface instead of the that of the library.
class Facade {
struct LibraryImpl : public Library {
int giveth() override;
};
LibraryImpl m_impl;
public:
int balance() { return m_impl.balance(); }
virtual int giveth() { return m_impl.giveth(); }
// don't declare taketh
};
int main() {
Facade f;
int g = f.giveth();
int t = f.taketh(); // compile error: undefined
}
Although I don't think your overall situation is good design, and I share many of the sentiments in the comments, I can also appreciate that a lot of code you don't control is involved. I don't believe there is any compile time solution to your problem that has well defined behavior, but what is far preferable to making methods private and not implementing them is to implement the entire interface and simply make any methods you can't cope with throw an exception. This way at least the behavior is defined, and you can even do try/catch if you think you can recover from a library function needing interface you can't provide. Making the best of a bad situation, I think.
If you have class A:public B, then you should follow the https://en.wikipedia.org/wiki/Liskov_substitution_principle
The Liskov substitution principle is that a pointer-to-A can be used as a pointer-to-B in all circumstances. Any requirements that B has, A should satisfy.
This is tricky to pull off, and is one of the reasons why many consider OO-style inheritance far less useful than it looks.
Your base exposes a virtual void foo(). The usual contract means that such a foo can be called, and if its preconditions are met, it will return.
If you derive from base, you cannot strengthen the preconditions, nor relax the postconditions.
On the other hand, if base::foo() was documented (and consumers of base supported) the possibility of it throwing an error (say, method_does_not_exist), then you could derive, and have your implementation throw that error. Note that even if the contract says it could do this, in practice if this isn't tested consumers may not work.
Violating the Liskov substitution principle is a great way to have lots of bugs and unmaintainable code. Only do it if you really, really need to.

Accessing a protected member of a superclass-typed member object - an elegant solution

First off, I know I can not do it, and I think it's not a duplicate questions (this and this questions deal with the same problem, but they only want an explanation of why it does not work).
So, I have a similar concept of classes and inheritance and I would, somehow, elegantly, want to do something that's forbidden. Here's a very simple code snippet that reflects what I want to do:
#include <iostream>
class A{
protected:
int var;
std::vector <double> heavyVar;
public:
A() {var=1;}
virtual ~A() {}
virtual void func() {
std::cout << "Default behavior" << this->var << std::endl;
}
// somewhere along the way, heavyVar is filled with a lot of stuff
};
class B: public A{
protected:
A* myA;
public:
B(A &a) : A() {
this->myA = &a;
this->var = this->myA->var;
// copy some simple data, e.g. flags
// but don't copy a heavy vector variable
}
virtual ~B() {}
virtual void func() {
this->myA->func();
std::cout << "This class is a decorator interface only" << std::endl;
}
};
class C: public B{
private:
int lotsOfCalc(const std::vector <double> &hv){
// do some calculations with the vector contents
}
public:
C(A &a) : B(a) {
// the actual decorator
}
virtual ~C() {}
virtual void func() {
B::func(); // base functionality
int heavyCalc = lotsOfCalc(this->myA->heavyVar); // illegal
// here, I actually access a heavy object (not int), and thus
// would not like to copy it
std::cout << "Expanded functionality " << heavyCalc << std::endl;
}
};
int main(void){
A a;
B b(a);
C c(a);
a.func();
b.func();
c.func();
return 0;
}
The reason for doing this is that I'm actually trying to implement a Decorator Pattern (class B has the myA inner variable that I want to decorate), but I would also like to use some of the protected members of class A while doing the "decorated" calculations (in class B and all of it's subclasses). Hence, this example is not a proper example of a decorator (not even a simple one). In the example, I only focused on demonstrating the problematic functionality (what I want to use but I can't). Not even all the classes/interfaces needed to implement a Decorator pattern are used in this example (I don't have an abstract base class interface, inherited by concrete base class instances as well as an abstract decorator intreface, to be used as a superclass for concrete decorators). I only mention Decorators for the context (the reason I want a A* pointer).
In this particular case, I don't see much sense in making (my equivalent of) int var public (or even, writing a publicly accessible getter) for two reasons:
the more obvious one, I do not want the users to actually use the information directly (I have some functions that return the information relevant to and/or written in my protected variables, but not the variable value itself)
the protected variable in my case is much more heavy to copy than an int (it's a 2D std::vector of doubles), and copying it in to the instance of a derived class would be unnecessarily time- and memory-consuming
Right now, I have two different ways of making my code do what I want it to do, but I don't like neither of them, and I'm searching for a C++ concept that was actually intended for doing something of this sort (I can't be the first person to desire this behavior).
What I have so far and why I don't like it:
1. declaring all the (relevant) inherited classes friends to the base class:
class A{
....
friend class B;
friend class C;
};
I don't like this solution because it would force me to modify my base class every time I write a new subclass class, and this is exactly what I'm trying to avoid. (I want to use only the 'A' interface in the main modules of the system.)
2. casting the A* pointer into a pointer of the inherited class and working with that
void B::func(){
B *uglyHack = static_cast<B*>(myA);
std::cout << uglyHack->var + 1 << std::endl;
}
The variable name is pretty suggestive towards my feelings of using this approach, but this is the one I am using right now. Since I designed this classes, I know how to be careful and to use only the stuff that is actually implemented in class A while treating it as a class B. But, if somebody else continues the work on my project, he might not be so familiar with the code. Also, casting a variable pointer in to something that I am very well aware that it is not just feels pure evil to me.
I am trying to keep this projects' code as nice and cleanly designed as possible, so if anybody has any suggestions towards a solution that does not require the modification of a base class every now and then or usage of evil concepts, I would very much appreciate it.
I do believe that you might want to reconsider the design, but a solution to the specific question of how can I access the member? could be:
class A{
protected:
int var;
static int& varAccessor( A& a ) {
return a.var;
}
};
And then in the derived type call the protected accessor passing the member object by reference:
varAccessor( this->myA ) = 5;
Now, if you are thinking on the decorator pattern, I don't think this is the way to go.
The source of the confusion is that most people don't realize that a type has two separate interfaces, the public interface towards users and the virtual interface for implementation providers (i.e. derived types) as in many cases functions are both public and virtual (i.e. the language allows binding of the two semantically different interfaces). In the Decorator pattern you use the base interface to provide an implementation. Inheritance is there so that the derived type can provide the operation for the user by means of some actual work (decoration) and then forwarding the work to the actual object. The inheritance relationship is not there for you to access the implementation object in any way through protected elements, and that in itself is dangerous. If you are passed an object of a derived type that has stricter invariants regarding that protected member (i.e. for objects of type X, var must be an odd number), the approach you are taking would let a decorator (of sorts) break the invariants of that X type that should just be decorated.
I can't find any examples of the decorator pattern being used in this way. It looks like in C++ it's used to decorate and then delegate back to the decoratee's public abstract interface and not accessing non-public members from it.
In fact, I don't see in your example decoration happening. You've just changed the behavior in the child class which indicates to me you just want plain inheritance (consider that if you use your B to decorate another B the effects don't end up chaining like it would in a normal decoration).
I think I found a nice way to do what I want in the inheritance structure I have.
Firstly, in the base class (the one that is a base for all the other classes, as well as abstract base class interface in the Decorator Pattern), I add a friend class declaration only for the first subclass (the one that would be acting as abstract decorator interface):
class A{
....
friend class B;
};
Then, I add protected access functions in the subclass for all the interesting variables in the base class:
class B : public A{
...
protected:
A *myA;
int getAVar() {return myA->var;}
std::vector <double> &getAHeavyVar {return myA->heavyVar;}
};
And finally, I can access just the things I need from all the classes that inherit class B (the ones that would be concrete decorators) in a controlled manner (as opposed to static_cast<>) through the access function without the need to make all the subclasses of B friends of class A:
class C : public B{
....
public:
virtual void func() {
B::func(); // base functionality
int heavyCalc = lotsOfCalc(this->getAHeavyVar); // legal now!
// here, I actually access a heavy object (not int), and thus
// would not like to copy it
std::cout << "Expanded functionality " << heavyCalc << std::endl;
std::cout << "And also the int: " << this->getAVar << std::endl;
// this time, completely legal
}
};
I was also trying to give only certain functions in the class B a friend access (declaring them as friend functions) but that did not work since I would need to declare the functions inside of class B before the friend declaration in class A. Since in this case class B inherits class A, that would give me circular dependency (forward declaration of class B is not enough for using only friend functions, but it works fine for a friend class declaration).

How and why is it possible to change access level of a member?

I ended up coding (With some help) something like this yesterday:
#include <iostream>
using namespace std;
class A
{
public:
virtual void foo(){cout << "A::foo\n";}
};
class B : private A
{
private:
virtual void foo(){ cout << "B::foo\n";}
void DoSomething(SomeOtherClass& o){o.DoSomething(*static_cast<A*>(this));}
};
I tried changing the inheritance method:
class B : public A
{
private:
virtual void foo(){ cout << "B::foo\n";}
};
int main()
{
A* a = new B;
a->foo();
}
This still works. I expected a compile time error. Please tell me why this is possible and what are the possible uses? I know one use due to first scenario - You can expose different interfaces for different classes.
EDIT:
In the second case, output is B::foo.
using namespace std;
class A
{
public:
virtual void foo(){cout << "A::foo\n";}
};
class B : public A
{
private:
virtual void foo(){ cout << "B::foo\n";}
};
int main()
{
A* a = new B;
a->foo();
}
This works because at compile time the compiler can only see that a is a pointer to the base class A and foo() is a public method being called on a, which is perfectly valid. The virtual binding happens dynamically at run time after the compilation, this virtaul binding decides that the actual call is to B::foo() and not A::foo() that is the the performance penalty of using virtualism.
May not answer all your questions directly, nevertheless I decided to put it up here for future reference. Also please take it with a pinch of salt as this is based on my understanding of the events that have happened in the C++ Standard world, rather than the actuals.
Read this. I don't have the ARM with me, but the article gives necessary details.
Note 115 in C++0x says
115) Access declarations are
deprecated; member using-declarations
(7.3.3) provide a better means of
doing the same things. In earlier
versions of the C++ language, access
declarations were more limited; they
were generalized and made equivalent
to using-declarations in the interest
of simplicity. Programmers are
encouraged to use using-declarations,
rather than the new capabilities of
access declarations, in new code.
In summary:
I think the ARM prohibited it initially:
An access declaration may not be used
to restrict access to a member that is
accessible in the base class, nor may
it be used to enable access to a
member that is not accessible in the
base class.
But later on I guess when the Standard evolved this was eventually allowed

Disallow fields in descended class C++

With a friend, we had following problem recently. There was a base class:
class A {
public:
A() : foo(10) {}
virtual int getFoo() const { return foo; }
protected:
int foo;
};
A friend implemented a class deriving from the one above.
class B : public A {
public:
void process() { foo = 666; }
protected:
//int foo;
};
Unfortunatelly he also added field foo in descendent class (commented line). So the following code.
#include <iostream>
int main()
{
A* aaa= NULL;
if (1) {
B* bbb = new B;
bbb->process();
aaa = bbb;
}
std::cout << aaa->getFoo() << std::endl;
return 0;
}
printed 10.
That's not the problem, since this will be totally redesigned, and such things won't happen in future.
I was just wondering, do you know any (portable) tricks or language patterns (besides obvious getters/setters; btw they were there actually, with foo being private), that would disallow declaring variable with the same name in descendent class (e.g. by causing compile-time error).
TIA!
No - you are not supposed to care about the implementation of the base class, so you should not be constrained in naming members in your derived class. And protected data is a bad idea.
You can make all your variables private then it doesn't matter if variables have the same name in descended classes, you'll always be accessing the correct variable - much better encapsulation which in turn will make your code easier to maintain in the long run.
PS : your test case does not need to be so complicated:
B b;
b.process();
b.getfoo();
will return 10 as well
C++ doesn't have a lot of features to protect you from mistakes. It doesn't really have any way to know what you intended and so can't tell what is really a mistake.
Not in the language itself, but some compilers can be configured to report certain types of warnings as errors. Consult your compilers documentation for reference.

How can I simulate interfaces in C++?

Since C++ lacks the interface feature of Java and C#, what is the preferred way to simulate interfaces in C++ classes? My guess would be multiple inheritance of abstract classes.
What are the implications in terms of memory overhead/performance?
Are there any naming conventions for such simulated interfaces, such as SerializableInterface?
Since C++ has multiple inheritance unlike C# and Java, yes you can make a series of abstract classes.
As for convention, it is up to you; however, I like to precede the class names with an I.
class IStringNotifier
{
public:
virtual void sendMessage(std::string &strMessage) = 0;
virtual ~IStringNotifier() { }
};
The performance is nothing to worry about in terms of comparison between C# and Java. Basically you will just have the overhead of having a lookup table for your functions or a vtable just like any sort of inheritance with virtual methods would have given.
There's really no need to 'simulate' anything as it is not that C++ is missing anything that Java can do with interfaces.
From a C++ pointer of view, Java makes an "artificial" disctinction between an interface and a class. An interface is just a class all of whose methods are abstract and which cannot contain any data members.
Java makes this restriction as it does not allow unconstrained multiple inheritance, but it does allow a class to implement multiple interfaces.
In C++, a class is a class and an interface is a class. extends is achieved by public inheritance and implements is also achieved by public inheritance.
Inheriting from multiple non-interface classes can result in extra complications but can be useful in some situations. If you restrict yourself to only inheriting classes from at most one non-interface class and any number of completely abstract classes then you aren't going to encounter any other difficulties than you would have in Java (other C++ / Java differences excepted).
In terms of memory and overhead costs, if you are re-creating a Java style class hierarchy then you have probably already paid the virtual function cost on your classes in any case. Given that you are using different runtime environments anyway, there's not going to be any fundamental difference in overhead between the two in terms of cost of the different inheritance models.
"What are the implications in terms of memory overhead/performance?"
Usually none except those of using virtual calls at all, although nothing much is guaranteed by the standard in terms of performance.
On memory overhead, the "empty base class" optimization explicitly permits the compiler to layout structures such that adding a base class which has no data members does not increase the size of your objects. I think you're unlikely to have to deal with a compiler which does not do this, but I could be wrong.
Adding the first virtual member function to a class usually increases objects by the size of a pointer, compared with if they had no virtual member functions. Adding further virtual member functions makes no additional difference. Adding virtual base classes might make a further difference, but you don't need that for what you're talking about.
Adding multiple base classes with virtual member functions probably means that in effect you only get the empty base class optimisation once, because in a typical implementation the object will need multiple vtable pointers. So if you need multiple interfaces on each class, you may be adding to the size of the objects.
On performance, a virtual function call has a tiny bit more overhead than a non-virtual function call, and more importantly you can assume that it generally (always?) won't be inlined. Adding an empty base class doesn't usually add any code to construction or destruction, because the empty base constructor and destructor can be inlined into the derived class constructor/destructor code.
There are tricks you can use to avoid virtual functions if you want explicit interfaces, but you don't need dynamic polymorphism. However, if you're trying to emulate Java then I assume that's not the case.
Example code:
#include <iostream>
// A is an interface
struct A {
virtual ~A() {};
virtual int a(int) = 0;
};
// B is an interface
struct B {
virtual ~B() {};
virtual int b(int) = 0;
};
// C has no interfaces, but does have a virtual member function
struct C {
~C() {}
int c;
virtual int getc(int) { return c; }
};
// D has one interface
struct D : public A {
~D() {}
int d;
int a(int) { return d; }
};
// E has two interfaces
struct E : public A, public B{
~E() {}
int e;
int a(int) { return e; }
int b(int) { return e; }
};
int main() {
E e; D d; C c;
std::cout << "A : " << sizeof(A) << "\n";
std::cout << "B : " << sizeof(B) << "\n";
std::cout << "C : " << sizeof(C) << "\n";
std::cout << "D : " << sizeof(D) << "\n";
std::cout << "E : " << sizeof(E) << "\n";
}
Output (GCC on a 32bit platform):
A : 4
B : 4
C : 8
D : 8
E : 12
Interfaces in C++ are classes which have only pure virtual functions. E.g. :
class ISerializable
{
public:
virtual ~ISerializable() = 0;
virtual void serialize( stream& target ) = 0;
};
This is not a simulated interface, it is an interface like the ones in Java, but does not carry the drawbacks.
E.g. you can add methods and members without negative consequences :
class ISerializable
{
public:
virtual ~ISerializable() = 0;
virtual void serialize( stream& target ) = 0;
protected:
void serialize_atomic( int i, stream& t );
bool serialized;
};
To the naming conventions ... there are no real naming conventions defined in the C++ language. So choose the one in your environment.
The overhead is 1 static table and in derived classes which did not yet have virtual functions, a pointer to the static table.
In C++ we can go further than the plain behaviour-less interfaces of Java & co.
We can add explicit contracts (as in Design by Contract) with the NVI pattern.
struct Contract1 : noncopyable
{
virtual ~Contract1();
Res f(Param p) {
assert(f_precondition(p) && "C1::f precondition failed");
const Res r = do_f(p);
assert(f_postcondition(p,r) && "C1::f postcondition failed");
return r;
}
private:
virtual Res do_f(Param p) = 0;
};
struct Concrete : virtual Contract1, virtual Contract2
{
...
};
Interfaces in C++ can also occur statically, by documenting the requirements on template type parameters.
Templates pattern match syntax, so you don't have to specify up front that a particular type implements a particular interface, so long as it has the right members. This is in contrast to Java's <? extends Interface> or C#'s where T : IInterface style constraints, which require the substituted type to know about (I)Interface.
A great example of this is the Iterator family, which are implemented by, among other things, pointers.
If you don't use virtual inheritance, the overhead should be no worse than regular inheritance with at least one virtual function. Each abstract class inheritted from will add a pointer to each object.
However, if you do something like the Empty Base Class Optimization, you can minimize that:
struct A
{
void func1() = 0;
};
struct B: A
{
void func2() = 0;
};
struct C: B
{
int i;
};
The size of C will be two words.
By the way MSVC 2008 has __interface keyword.
A Visual C++ interface can be defined as follows:
- Can inherit from zero or more base
interfaces.
- Cannot inherit from a base class.
- Can only contain public, pure virtual
methods.
- Cannot contain constructors,
destructors, or operators.
- Cannot contain static methods.
- Cannot contain data members;
properties are allowed.
This feature is Microsoft Specific. Caution: __interface has no virtual destructor that is required if you delete objects by its interface pointers.
There is no good way to implement an interface the way you're asking. The problem with an approach such as as completely abstract ISerializable base class lies in the way that C++ implements multiple inheritance. Consider the following:
class Base
{
};
class ISerializable
{
public:
virtual string toSerial() = 0;
virtual void fromSerial(const string& s) = 0;
};
class Subclass : public Base, public ISerializable
{
};
void someFunc(fstream& out, const ISerializable& o)
{
out << o.toSerial();
}
Clearly the intent is for the function toSerial() to serialize all of the members of Subclass including those that it inherits from Base class. The problem is that there is no path from ISerializable to Base. You can see this graphically if you execute the following:
void fn(Base& b)
{
cout << (void*)&b << endl;
}
void fn(ISerializable& i)
{
cout << (void*)&i << endl;
}
void someFunc(Subclass& s)
{
fn(s);
fn(s);
}
The value output by the first call is not the same as the value output by the second call. Even though a reference to s is passed in both cases, the compiler adjusts the address passed to match the proper base class type.