Zero-overhead abstraction is a key talking point of the language. Virtual-by-default would contradict this entirely.
These days, the economy of a vtable pointer is not really a good reason, and all languages that have the opposite default (such as Java, as you point out) are doing quite fine.
Because of this default, I can't count the number of times where I've seen "#define private public" and other horrors that developers used to be able to extend classes that their creators were too short sighted to design properly.
If anything, the performance difference between std::vector<shared_ptr<Foo>> and std::vector<Foo> is even greater today than it was twenty years ago.
Not being able to inline a method like (from vector)
T& operator[](size_t pos)
{ return data[pos]; }
Would kill performance.In languages which do run-time optimisation you can inline such methods later, but in C++ that's not possible and proving when you can de-virtualise a method (which most compilers do) is very hard and often fails.
The reason the previous commenter asked if you're from the java world is because in many highly important areas, the effect on memory and speed this would cause would be unacceptable. These areas _tend_ to be left to people who understand languages like c, though, so a lot of newer languages make decisions ignoring these good use cases.
Also I don't think it's that big of an achievement to understand C. Despite its flaws it's very simple language, very different from C++.
To the point - you could ensure that compiler can de-virtualize your usage of structure (or class if you will) by adding "nonvirtual" to every method it implements or derives. I don't see how it's any better than having to delete "virtual" from every method it implements or derives. Just a question of defaults, and I'd say most of modern C++ code isn't written with the performance goals that justify nonvirtual as default. You can and should profile after writing something anyway if you care about performance.
And anyway if you have derived classes it's almost always the case that you want at least some of your methods virtual, otherways what's the point?
In practice, most classes are designed without inheritance in mind and yet, being able to extend and override them has proven infinitely more valuable than the occasional case where such an overriding breaks the parent class.
The practical reality is that even if a class is not designed for inheritance, inheriting from it is unlikely to break it but very likely to make its user's life much, much easier.
tl;dr: Just because it's "infinitely more valuable" in Java doesn't mean the same for C++.
Think it in this way. Many respectable people has been making a case to avoid inheritance[1][2]. What you are proposing would actually be an incentive to them. I don't know about you but the amount of functions that I actually override in my code is not even close to the 20%.
Why should we set a default for that 20%?
[1] http://channel9.msdn.com/Events/GoingNative/2013/Inheritance... [2] http://www.gotw.ca/publications/mill07.htm
And you do want to refactor your virtual methods and then extracted methods do usually need to be virtual, even if at first they don't they may need to become virtual in future, and IMHO it's better to just make them virtual from the start, if you don't REALLY need the performance.
You can mess up because of nonvirtual-by-default too, especially in C++ because of the difference between stack and heap objects.
struct A {
virtual int f(int x, int y) { return g(x,y); }
int g(int x, int y) { return x+y; }
};
struct B : public A {
int f(int x, int y) { return g(x,y)+1; }
int g(int x, int y) { return x+y-1; }
};
B* b1 = new B();
A* b2 = b;
B b3;
b1->f(2,2); // 4
b2->f(2,2); // 5
b3.f(2,2); // 4
This bite me a few times in C++.The override keyword was added in C++11 to help prevent the sort of mistake you were trying to show. Any methods you mark with it will result in a compile error if they are not actually overriding anything.
For example, if B::g were marked as override, it would fail to compile because A::g is not virtual.
Unfortunately, class inheritance is the only way to create the equivalent of an interface or (Scala-type) trait in C++. So, even if you avoid class inheritance in general (which is a good thing IMO), you still end up doing inheritance if you want run-time polymorphism in the form of abstract classes or abstract base classes.
I am using C++ right now for embedded code but otherwise I write mostly Javascript. There was a time when C++ was the standard choice of language for desktop apps etc., but that's hardly the case any more. You choose C++ if you need performance and control. And I think the "default means the least overhead" concept makes a lot of sense there.
Also, inheritance is a very central part of mostly all Java code whereas it's much less idiomatic (modern) C++. In C++, classes serve to give you RAII and you specialize with templates.