The compiled code is native but you need an additional library (the runtime) which does all the object and message handling (lookup, invocation etc.). There is no virtual machine involved. So it is more like QT than Java runtime.
[Update]
Since the C++ message binding behaviour is not obvious to programmers of more dynamic OO languages (e.g.: Objective-C or Smalltalk) - like me - I wrote a small C++ test app which demonstrates the effect of the virtual
keyword on the choice of the method to call.
#include <iostream>
class Test1 {
public:
Test1();
void test1();
void test2();
};
class Test2 : Test1 {
public:
Test2();
void test1();
void test2();
};
Test1::Test1() {}
void Test1::test1() { std::cout << "T1:t1" << std::endl; }
void Test1::test2() { std::cout << "T1:t2" << std::endl; }
Test2::Test2() {}
void Test2::test1() { std::cout << "T2:t1" << std::endl; }
void Test2::test2() { std::cout << "T2:t2" << std::endl; }
int main(int argc, char **argv)
{
Test1 *t11 = new Test1();
Test1 *t12 = (Test1 *)(new Test2());
Test2 *t2 = new Test2();
t11->test1();
t11->test2();
t12->test1();
t12->test2();
t2->test1();
t2->test2();
return 0;
}
An Objective-C programmer would expect a output of
T1:t1
T1:t2
T2:t1
T2:t2
T2:t1
T2:t2
since t12
is actually a Test2
which was casted to Test1
.
The actual output is
T1:t1
T1:t2
T1:t1
T2:t2
T2:t1
T2:t2
because C++ (by default, i.e. without virtual
) statically binds the call to test1
based on the type it knows at compile time which is Test1
(due to the cast).