5 ms·
Uh, no, "virtual" should absolutely NOT be the default. I don't know where you got that idea from (Java?) but it's absolutely horrible.
by wfunction 12y ago
Uh, no, "virtual" should absolutely NOT be the default. I don't know where you got that idea from (Java?) but it's absolutely horrible.
- ajuc 12y agoWhy would it be bad? You could always add non-virtual (inline maybe? it's already useless keyword) if you need the performance, and most of the code doesn't. And it's a source of errors.
- ixtli 12y agoBecause if the compiler can not figure out how to de-virtualize your usage of a structure then you're going to necessitate that a vtable be created at compile time and used at runtime. 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.
- ajuc 12y agoI don't know which world I'm from. I mostly program (for money) in java nowadays, but I also did C++ for money for like 6 years, and I knew C years before. And mostly I've learnt programming on turbo basic and turbo pascal. But never had to do system programming. 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?
- wfunction 12y agoPerformance is only one side of it. The bigger reason is http://stackoverflow.com/a/814939 http://stackoverflow.com/a/814939
- zak_mc_kracken 12y agoOver 20+ years of development, I've found this objection to be vastly theoretical and with no practical consequences. 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.
- wfunction 12y agoSeemingly off-topic, but I'm curious -- what language has the majority of your 20+ years of development been in?
- zak_mc_kracken 12y agoProfessionally, Java for most of the time. Recreationally, Scala and Haskell. I did about 5 years of C++ overlapping with Java before that.
- wfunction 12y agoOk, that explains it. When you're used to Java it's easy to expect inheritance to be a big deal. The fact of the matter is that run-time polymorphism (aka virtual) is much more rarely necessary in the C++ world than the Java world. The only reason it's common in Java is that it's the only tool available for many job that C++ has other tools for, and it also avoids an extra composition overhead that doesn't exist in C++. tl;dr: Just because it's "infinitely more valuable" in Java doesn't mean the same for C++.
- dasmithii 12y agoI wouldn't call it 'horrible', but rather, inconsistent with C++ and its target area. Zero-overhead abstraction is a key talking point of the language. Virtual-by-default would contradict this entirely.
- zak_mc_kracken 12y agoIt was the right default twenty years ago for performance reasons. 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.
- jonstewart 12y agoI'm very glad that virtual is not the default. Most of the classes I write are simply value classes and do not use inheritance at all. Once you start using virtual, you really have to embrace traditional inheritance idioms whole hog, and then you've got std::vector<std::shared_ptr<Foo>> instead of std::vector<Foo>. 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.
- ufo 12y agoOn the flipside, if you are not using inheritance then you could have solved the same problem with abstract data types. The only big problem is that in C++ the method call syntax is much more convenient to use: foo.frob() vs Foo::frob(foo). IMO, the correct way to fix this is by adding syntax sugar to the language, not by making methods non virtual by default.
- jonstewart 12y agoI don't understand. Do you mind elaborating? Not sure what you mean, specifically, by "abstract data type" (I think of ADT as just another synonym for a class), nor do I get the static method thing. If you were calling hard-coded static methods, you wouldn't have polymorphism anyway, so how you have virtual methods?
- CJefferson 12y agoThe real problem with defaulting to virtual isn't the vtable pointer, it's the lack of inling. 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.