Oh... and DinkumWare wrote the STL implementation that Microsoft includes with its compilers...
Printable View
Oh... and DinkumWare wrote the STL implementation that Microsoft includes with its compilers...
I agree with Darwen that inheritance is a wonderful thing. But you have to keep in mind that every tool is built with a different purpose in mind. Each of which have their own limitations (including MFC) and their strengths. MFC has a ton of thread dependencies that make it a real pain to use in multi-threaded programming. This is because Microsuck decided to 2store information on a thread specific basis. In doing so they created problems with creating MFC objects in one thread and using them in another. And no I am not referring to just a simple synchronization issue. In some cases you simply cannot use a class in a thread outside of the one that instantiated it.
Moving back to STL, it was designed to be portable, light, and extremely fast! And it meets all of these requirements and then some. Place virtual destructors in STL would do nothing but hurt performance because the compiler would have to generate a V-table. In most cases this performance hit might not be substantial but it would hurt the design of STL.
As for the STD:: blah blah....that's just a ridiculous comment. If you've been developing in C++ for so long than you should be using namespaces in your own applications. They are very important in large scale development projects. Of course if all you do is work on Hello World, than I could understand why namespaces aren't so important to you.
I would like to suggest to anyone that doesn’t like STL, try building an application that uses “Cstring” and one that uses “std::string” to see which one performs better. You’ll understand what I mean if you just spend the time to look at other tools. MFC is great for some things but don’t use it to build a Windows NT service and expect to get a lot of performance out it. Besides, basing an opinion of a technology on the fact that you can’t inherit from it doesn’t make any sense at all. There are a lot of factors that should go into these kinds of comparisons.
To sum this all up…STL rocks! It’s fast…efficient…and very easy to use.
If you think Microsoft's code is written in some fashion to gain optimal speed from their compiler you are WAY WRONG!!! Actually, I can't even begin to tell you how wrong that statement is.
Take some advise and download Intel's C++ compiler and build an MFC, STL, and any other application that you like using their compiler. Than compare the performance between the two. You will find that Intel's compiler kicks the crap out of Microsoft's any day.
Microsoft makes a great IDE (Visual Studio) but they don't concentrate on the compiler to the extent that Intel does. Keep in mind the Intel C++ compiler is a plug-in for Visual Studio so you can install it and switch between the two compilers with ease.
Give it a try...I promise you will never want to return the Microsoft compiler again!
I still see no reply to the iterator and allocator abstraction advantages. Particularly since the iterator abstraction gives all the same extensibility options that derivation might give, but allows such extensions to work over entire classes of iterators and containers instead of just one type as inheritance would. There is no need to access the internals of the classes as well (which would be horribly nonportable... is the data stored in _pData or _memoryBlock, what is its type, etc.). And by the encapsulation rules of Sutter and Myers, this would mean that the function should not be a member of the class anyway, but instead should be a stand-alone algorithm. These are basic good design issues that are handled perfectly with STL and very poorly or not at all with the MFC containers.
I am a firm believe in using tools to help get the job done. Which means that I use tools like BoundsChecker to capture bugs in the code instead of playing with the debug runtime settings. Don't get me wrong, the debug runtime stuff can really help but it doesn't catch all times of errors. Like when someone allocates an array on the stack and then causes a buffer overflow with strcpy() or some other function. But BoundsChecker catches just about everything. Go Numega!!! Go BoundsChecker!!! And no I don't work for Numega. LOL.
Some other really cool tools are Intel's VTune (awesome performance analyzer) and Numega's TrueTime (another cool performance analyzer).
If your company is too cheap to purchase such tools...tell them to get out of the software business. Please. :=)
Happy coding.
This discussion reminds me of other discussions -- "qsort, QSort vs. std::sort" -- or "why referencies are useless" -- or "why it is ok to return pointers to local objects". The regular members of the forums will know what I am talking about.
The original poster started this thread with an affirmation ("I hate STL") and proved that he will defend this point no matter what. This is not a discussion any more, it is a flamewar. The reason why this thread is still alive is that it provides a few usefull points of view and that the language used is reasonable.
However, reading things like "namespaces are useless", or that "a design is not really OO beacuse it doesn't use a lot of inheritance" make me want to bang my head agains the keyboard. But I know from experience that it makes no sense to quote renomed C++ specialists or to write long posts full of decent arguments in such a case.
darwen, before starting another thread like this, please think twice!
I am surprised at the lack of balance in this debate. MFC and STL were architected to meet different needs of differing communities of developers. Rather than debate which library is ‘better’, I suggest you review the strengths and weaknesses of each so that you’ll be able to identify and apply each in the proper context.
If you truly do not understand the tradeoffs (size, space, speed, flexibility, coupling, and cohesion) between subtype polymorphism (inheritance) and parametric polymorphism (templates) then I hope your impact on commercial systems is limited to “coloring inside the lines” of someone else’s design.
This is not a personal attack; simply an view honestly expressed. Like so many other domains – software engineering suffers from the tyranny of the majority. Our field is perceived by the quality of the ‘average’ product produced by the ‘average’ programmer and the quality of both of our averages is far to low.
As far as whether either MFC or STL is OO (or good OO), it simply doesn’t matter. OO is so 80’s and 90’s. What matters is generic, efficient (provably), and reusable software using all means provided to maximal achievement. Inheritance vs. Templates, Function Templates vs. Overloads, Members vs. Friends vs. Out-of-Bodies; there is no “one true way”. No single style or subset of a language is best for all occasions. If so, our languages would simply be smaller. Basic computability theory proves that for any algorithm there are an infinite number of result-equivalent implementations yet each has a unique signature in its path to a common result – meaning differences in size, space, speed, etc.
There will always be numerous ways to reach an end – whether in C++ or any other language. Programmers who grasp the language understand that each way is necessary and not in fact duplicative.
Well, as I understand this thread, it is a comparison of MFCQuote:
Originally posted by mclark
I am surprised at the lack of balance in this debate.
containers and STL (or STC if you like). So where is the
lack of balance? Unless you mean that Darwin is off-balance in
his dogmatic refusal to accept the truth.
Well why don't you start this review? To me MFC is a GUI library thatQuote:
MFC and STL were architected to meet different needs of differing communities of developers. Rather than debate which library is ‘better’, I suggest you review the strengths and weaknesses of each so that you’ll be able to identify and apply each in the proper context.
wraps the Win32 API and adds some extensions like DOC/VIEW.
I have not been pleasantly surprised by any of the lower level
tools and try to avoid them whenever possible, either by writing my own wrappers or turning to boost or the standard.
So what community is MFC geared for? The key word here is GUI.
IMO It is for allowing people to churn out a user interface quickly
and without really knowing what is going on.
At the lower levels of my program I want things to be small and
task specific and I want control. I don't want the "evil MFC framework"
playing any role in my objects to latter come back and bite me on the a_s_s.
Again, how about some details. I am not trying to be rude, it isQuote:
If you truly do not understand the tradeoffs (size, space, speed, flexibility, coupling, and cohesion) between subtype polymorphism (inheritance) and parametric polymorphism (templates) then I hope your impact on commercial systems is limited to “coloring inside the lines” of someone else’s design.
just that it would be nice to learn something. I don't disagree
with anything you said.
I don't know how to quite express my thoughts here. I can't
really talk about performance without just quoting someone else, so I will talk about semantics. To me a container
like a vector is a basic object. You don't inherit from it to extend
its capabilities; you write template classes which contain it or
write algorithms to manipulate it. Forgive me if everyone disagrees with this, it is just a point of view I have come to.
To me template programming represents a higher level of
abstraction than inheritance. And adding levels of abstraction
allows one to say and accomplish more with less. Don't get me
wrong, inheritance definitely has its place, but to rigidly demand it
in all situations is silly. A vector is a vector. The usual reason to want to inherit from it is, for example, to have a vector that does this or
that. I believe the proper way to think is that I have a vector that I perform this or that on, not a vector that does this or that.
It is so 90's to say it is so 80's and 90's:)Quote:
As far as whether either MFC or STL is OO (or good OO), it simply doesn’t matter. OO is so 80’s and 90’s.
And another thing, why do people keep indicating you can't
use MFC serialization with STL containers. Of course you can.
Darwin have you read the source code for CArchive to see what it does with a MFC contianer? It is easy enough to do the same
thing if you want to use archives with c++ objects.
Very interesting discussion. Always the same arguments.
Normally this tends to be more religious than
rational. If such a narrow minded view does also apply
to other skills of you, you will (too) soon find out that the same
special work you do also can be done by indian or chinese workers as well. At a much lower cost I might add.
Perfection in programming is not the argument for job security.
You really should keep this in mind.
First let me say that my experience with MFC is limited. Most of my systems use commercial or proprietary RTOSes. So my insight into MFC is far from definitive. STL on the other hand I have significant practical experience with and David Musser (one of the founding authors of STL) was a professor of mine during my undergraduate work at RPI. Yes, you would think that this would unfairly bias me towards STL but the opposite is true. Early versions of STL (including those that morphed into the HP version) were horrendous to use. I spent many years since avoiding STL where possible. It has been a hard road back to recognize STL’s true genius.
But from my limited view I don't think your analysis of MFC as...
is that far off. It does seem as though its primary purpose is to provide an OO interface to the WIN32 API. This is of course very useful. How many times have we looked on in disgust at a beautifully crafted object that is forced to embed an OS C system call (ala POSIX or WIN32)?Quote:
... MFC is a GUI library that wraps the Win32 API and adds some extensions like DOC/VIEW.
STL on the other hand was intended to provide a library of ‘generic’ containers and efficient algorithms for operating on containers. In STL the term ‘generic’ does not simply mean reusable but relying on only the most basic of semantic relationships as forwarded by the ‘generic programming’ sub-discipline. In STL the generic philosophy can be seen manifest in the relationship between containers, interators and algorithms. Iterators provide the access and operations for containers as required by algorithms so allowing algorithms to interoperate with any number of differing types of containers. Since a container need only provide the correct iterator to be useable by an algorithm – no inheritance (IS-A, refinement) relationship need exist between containers. This in turn allows each container’s interface to be unique to its intent and capability and eliminates performance and design coupling associated with virtual functions. The tradeoff is that the type of the container (or actually the iterator’s type) must be determinable at compilation time.
If types truly cannot be ‘known’ at compilation time then inheritance is required though it is often useful even when the types are known to control the code-bloat associated with templates which would have to be instantiated on a large number of types.
Everyone knows that you can use STL containers on polymorphic data but since you cannot inherit (safely) from STL types, people assume that you cannot have run-time polymorphic STL objects (ie. Run-time determination of what container type you are passing into an algorithm). This can easily be achieved though a customer iterator type that contains a polymorphic member. In this way, the exterior iterator type (your custom iterator) passed to the algorithm is static, yet the iterator forwards operations to a polymorphic member whose type is run-time dependent.
I know, I know. Its just hard in a busy schedule to find the time to whip up meaningful example code for a discussion forum. The polymorphic member approach is heavily used in policy-based libraries like LOKI from A. Alexandrescu's "Modern C++ Design: Generic Programming and Design Patterns Applied" (a most mis-titled book) but not for STL. If someone is very VERY intrested I will put together the code for polymorphic iterators.Quote:
Again, how about some details. I am not trying to be rude, it is just that it would be nice to learn something.
A virtual function call is always more expensive than a normal function call unless the compiler can determine the type – but since we are assuming that inheritance was dictated by at least one instance where the type is ‘unknowable’ it is fair to say that overall it is more expensive. But it is the only way. If you really need run-time polymorphism (either because types are unknowable or instantiation of templates on all required types is to great) then you must pay for it. Nothing including polymorphism is free.
The real difference on the inheritance vs. templates in MFC and STL is that STL does not require you to pay for something unless you use it. If you want run-time polymorphism of STL objects (not just STL objects containing polymorphic data) then you have to pay for it using run-time polymorphic members within your own iterator type.
As far as the single-rooted hierarchy style of MFC – there are a number of papers/books critiquing this design style. Given MFC’s focus on GUI construction, the single-rooted approach is of no surprise since there is a strong history of single-rooted hierarchies in OO GUI tool-kits.
We are in violent agreement.Quote:
A vector is a vector. The usual reason to want to inherit from it is, for example, to have a vector that does this or that. I believe the proper way to think is that I have a vector that I perform this or that on, not a vector that does this or that.
STL is ok upto a point
Anybody tried building DLL using the STL? It's difficult as you have to export the derived templated STL class.
Even worse some won't even export, map for example.
I have resorted to implementing my own simple collection classes CVoidMap and CMultiList.
Aha MultiList.
CMultList maintains many lists and moves entries from one list to another without re-allocating memory (deletes move entries to a free list). Usefull if you want to avoid memory fragmentation. The object pointed to by the multi list entry remains where it was allocated.
E.G. So you have 2 lists - Active and Inactive. When an object becomes active move it to the active list. When inactive move it back again. Only pointers to list entries are updated.
Want it ?
e-mail [email protected]
That is a deficiency of DLL's not handling C++ templates. DLL's were not made to handle C++ templates nicely or correctly (note that this is with all template classes, not just STL classes).Quote:
Originally posted by Bob Sheep
STL is ok upto a point
Anybody tried building DLL using the STL? It's difficult as you have to export the derived templated STL class.
Even worse some won't even export, map for example.
Regards,
Paul McKenzie
Interesting topic....so of coarse I've got to throw my 2 cents in :)
First I didn't know people were still using STL in production code.
One of the first rules about coding, at least for me, is that all code I write or use must be easily debugable. Meaning, if I have to run around in a whole bunch of badly written STL lines of code to find a problem, I'm losing time, and as we all know, time costs money...
Another rule, all code must be easily reusable. While STL is indeed reusable, when you get to complex container use, its gets overly confusing and very hard to reuse (nevermind insane to debug). Which makes STL great for the one time slap a 'int' container together program. Otherwise known as a homework assignment....
In my many years of programming, I've seen that most professional programmers write their own code and expand it to complete all that is missing in other peoples code.
An example for MFC is CString... I haven't used CString in years. I have since written my own class which does everything CString does in full binary and a whole bunch more like full token parsing, file parsing, easy indexing, page development, and easy to pass around between dlls and processes with out memory leaks or MFC boundry issues....Nevermind its ease to use it in any container class. CString and MFC are great for the casual programmer, but in the real world when you're writing a million dollar piece of software, you don't have time to write the odd function here and odd function there to compensate for MFC's or STL's badly designed code...you need something that you can trust to work and wont change no matter what system you drop it on or what program you need to create. Less time you spend, more profit for you :D
The only MFC class I use is CWnd and that's so I don't have to mess around with the API when creating my own controls. This is another example of where you want a control to look the same on all Windows systems, so you draw the thing yourself. Yes, it takes a little extra time, but over the years you build your own library of code that you can trust and makes it easier for you to create programs. Which is why I can slap entire applications together in minutes that would take someone in MFC or STL hours to do...
So the moral of the story is:
You like STL or MFC? Cool, learn from it...write your own templates and classes...expand it....but don't use that crap in a professional program unless you like being unemployed…
You should have your own libraries full of code you know how to use and know that works, and have added lots of wonderful and useful things to, that will make your job very easy in future projects.
Don't believe me? I have time to write this cause my boss gave me an hour to write a program that uses a drag-n-drop listctrl to convert our proprietary formats to any common image type, I did it all using only CWnd in MFC as a base class for my ctrls and dialog, and everything else was my own code...it took me 15 minutes... (I've always meant to go back and replace CWnd...but it works great and with ease...so eventually...)
So which is better? Neither, they both suck, write your own code :)
Back to work!
The personal 'everything and the kitchen sink' library might work very well on the desktop but not all environments are so forgiving.Quote:
You should have your own libraries full of code you know how to use and know that works, and have added lots of wonderful and useful things to, that will make your job very easy in future projects.
There are other domains where every cycle, every byte and every bug count. Balancing functionality, standardization, performance and trust is not always as easy as 'roll your own'.
I've been employed for over 20 years, and I use STL all the time. Using your method is the fastest way of being unemployed, if not, unemployable.Quote:
Originally posted by oktronic
So the moral of the story is:
You like STL or MFC? Cool, learn from it...write your own templates and classes...expand it....but don't use that crap in a professional program unless you like being unemployed…
And this is what STL provides. I know how to use it, I know how it works, and I've added lots of wonderful and useful things to it by using the algorithm classes.Quote:
You should have your own libraries full of code you know how to use and know that works, and have added lots of wonderful and useful things to, that will make your job very easy in future projects.
Your method will make the job of the next programmer who has to maintain your code less enjoyable. When there is a bug or something needs to be added, the programmer that is hired to look at your code now has to work doubly hard to understand what you are doing, and where to add this functionality (if the functionality can be added).
You may work as a sole-programmer, but when it comes down to brass tacks, your method is the one that will lose time and money, not the other way around. In most professional environment, your home-made code would be tossed in the trash bin -- it may be the greatest code you've ever written, it doesn't matter. It will be removed in favor of standard components. Why?
a) maintenance
b) cost of training someone to use your home-made library.
c) thousands of programmers have tested and used them
d) documentation can be easily found on any of the standard components.
I guess you are a 'C' programmer who learned C++ later, right? Usually it is these programmers who want to write everything themselves (but for some reason, they never feel compelled to right their own FILE* functions or strcpy(), or memcpy(). I wonder why?).Quote:
So which is better? Neither, they both suck, write your own code :)
The STL classes are written by some of the best C++ programmers in the world. They are not fly-by-night programmers who made up these classes, as your last paragraph suggests.
Also, you don't choose a technology because a certain debugger doesn't show you the data that you want. Really, that is a naive approach to programming -- depending on how fancy the debugger shows you data. If the next version of VC++ has the greatest debugger in the world that shows you everything, will you then use the STL classes?
Regards,
Paul McKenzie
indeed mclark,
Design, design, design....
I'm a huge fan of encapsulation. Everything is broken up in nice modules, static libraries and dlls. Depending on what it is and how its useful...
I'm 99% windows, but things that can be used elsewhere are set up to be.
Sorry Paul, didn't notice your response, guess you posted as I did...
Shall we begin...
QUOTE]I guess you are a 'C' programmer who learned C++ later, right?[/QUOTE]
Most of us senior programmers are, Paul. This might comes as a shock, but C came before C++. There were a whole bunch of languages before C++ surprisingly....
Nothing personal, but I kind of doubt this...maybe 10...besides the most obvious reason that STL isn't that old and wasn't used in a commercial compiler until mid to late 90's, there is this:Quote:
I've been employed for over 20 years, and I use STL all the time
You see Paul, every professional C programmer when they migrated to C++, and I stretch the term migrated, took their existing code and libraries and converted it to be object orientated...well, those of us who liked the idea of C++ anyways.... So we programmers, who have actually programmed for 20 years+, would have converted or kept our existing C or C++ containers...why? Because what works, works...there's no need to take a class which is new and replace bug free, fully functional code that has withstood the test of time....many companies wouldn't even allow C++ when it came out to be used for this very reason...
This is another example of what I was talking about above about the inexperience.Quote:
You may work as a sole-programmer, but when it comes down to brass tacks, your method is the one that will lose time and money, not the other way around.
In my experience as an employee and as a consultant, companies prefer non-dependant code to SDK libraries that are subject to change. Generally when you supply your own code to a project, a company, when you leave, will buy the rights, if you have any, or purchase use of your code for a nice fee.
I've held many contracts in my hand that do not allow the use of STL or MFC, since both are subject to change. At some point the program will need to be compiled again, or MFC will change and then a new bug may be introduced into the system. When your program is required to run for years with out any problem at all, which is the work I do the most, you can not afford the liability of code stopping to work because of an update.
First, there are no algorithm classes, they're all template functions, so unless you are talking about something else then the STL algorithm functions, I'm confused....and if you are talking about the functions, then your statement loses weight.Quote:
And this is what STL provides. I know how to use it, I know how it works, and I've added lots of wonderful and useful things to it by using the algorithm classes
a) well designed code doesn't require maintenance.Quote:
a) maintenance
b) cost of training someone to use your home-made library.
c) thousands of programmers have tested and used them
d) documentation can be easily found on any of the standard components.
b) if you have to train a C++ programmer to read C++, C, or function documentation, then you've hired the wrong guy.
c) you mean thousands of buggy college programs?
d) MSDN does have documentation, its hardly understandable for even the average C++ programmer. Sadly, the technical writer and the programmers who explained it didn't quite understand it, so they used a lot of the original documentation, which is why MSDN is so vague, the original writers didn’t think it would go far enough to need further explanation. That’s why it reads like R&D notes.
I'd love to tell you all about this, but instead I'm just going to laugh real hard...Quote:
The STL classes are written by some of the best C++ programmers in the world
Guess you never opened one of the header files....Quote:
They are not fly-by-night programmers who made up these classes
Yes you do. Again, time is money. If you're paying a programmer $15/hr, then no, you loss is minimal if he has to spend an additional hour sifting badly written code to find a problem.Quote:
Also, you don't choose a technology because a certain debugger doesn't show you the data that you want
However, when you pay $200/hr to $10000/day, then you can't afford to spend time screwing around. So yes, you can reject a technology for costing you unnecessary money.
So Paul, I hope I've covered everything for you. No disrespect is intended by this, simply clarification.
Regards,
Oktronic
Well I haven't even been programming for a year and a half and
I have enough sense to know what you are saying is BS.
Standardization
Oh boy, this has been running for a long time since I started it !
Right, addressing a few points :
(1) Writing all you own code from scratch.
Are you mad ? Don't you ever think of moving companies ? If you do you'll have to do it all again otherwise face those nasty people called lawyers.
Never mind the fact that it makes your code unreadable to everyone else because no-one knows your class hierarchy. True you can say that your own code has to be interpreted by others anyway but if it's based on MFC (and when I say MFC I'm not refering to the GUI classes, I'm refering to things like CMapStringToPtr and CMapStringToOb and CDWordArray and CString etc etc) or STL at least people have half a chance of understanding the basics of it.
If you use your own set of base classes it'll make your project's learning curve for anyone else having to maintain it massive.
(2) Standardization.
Yep good point. But MFC has been around for at least as long as STL and in some compilers (ok mainly microsoft) longer so it's about as close to standard as you can get. So I would argue if you're not looking at cross platform support then MFC is just as standard as STL to the Windows programmer.
(3) Yep I'm a senior programmer, and no I still don't like STL.
Look, it's just my personal preference as I have said here before so I don't expect flames.
Not being able to debug STL (or rather track down memory leaks) is a major disadvantage in my opinion. This is because DEBUG_NEW doesn't work with STL.
However, I just don't like the way it LOOKS. All the templated <> blah blah make the code look really messy. And I can't tidy this up easily by inheriting from stl classes to make them more readable.
Someone has said that inheritance is a bad thing. Why is it in object oriented design then ??!! Actually its a very fundamental part of object oriented design. Are you saying that the C++ standard is wrong now ?
In actual fact my opinion is that its really nice we're having this discussion at all. The fact that C++ is so flexible (ok not particularly type safe) that we can choose which way we prefer to do things is lovely. So long as we adhere to good design and implementation standards the sky's the limit. And we can do this either with STL or MFC and both methods are equally as valid.
Darwen.
I'm not talking about the language, but the mindset. Most C programmers who do not know to use C++ properly bring over the C coding habits. This can lead to disastrous results.Quote:
Originally posted by oktronic
Most of us senior programmers are, Paul. This might comes as a shock, but C came before C++. There were a whole bunch of languages before C++ surprisingly....
Hmm. You doubt my experience -- I guess this is your tactic to try and bolster your argument.Quote:
Nothing personal, but I kind of doubt this...maybe 10
I said I have been programming for 20 years. Please read carefully.Quote:
...besides the most obvious reason that STL isn't that old and wasn't used in a commercial compiler until mid to late 90's, there is this:
Well, many companies have thrown away their old code with the full knowledge that the standard classes today are fully functional, debugged, standard, and yes, dare I say, superior to what was done previously. When C++ first came around, there were no standard classes, so I can see where the need to create your own needed to be done. Now that is no longer the case.Quote:
You see Paul, every professional C programmer when they migrated to C++, and I stretch the term migrated, took their existing code and libraries and converted it to be object orientated...well, those of us who liked the idea of C++ anyways.... So we programmers, who have actually programmed for 20 years+, would have converted or kept our existing C or C++ containers...why? Because what works, works...there's no need to take a class which is new and replace bug free, fully functional code that has withstood the test of time....many companies wouldn't even allow C++ when it came out to be used for this very reason...
The STL is not an SDK library, it is part of the language library. Why do you still insist that STL is something external, when it is part of the core language library? Again, do you consider the stdio functions, the C-string functions, the C time and date functions, etc. "SDK libraries"? If not, why not? Do you consider <complex> and <iostream> part of the language library, or an "SDK library"? Neither are STL. I think you are confused.Quote:
This is another example of what I was talking about above about the inexperience.
In my experience as an employee and as a consultant, companies prefer non-dependant code to SDK libraries
Maybe you are confused. First, I'm strictly talking about the STL language library, already standardised by ANSI. I am not talking about MFC or any other GUI library that are not standardized.Quote:
that are subject to change
When I supply my code to a project, if it contains home-made code that is already been done via the standard library, I get the code thrown back at me to fix it.Quote:
Generally when you supply your own code to a project, a company, when you leave, will buy the rights, if you have any, or purchase use of your code for a nice fee.
For STL, it is already standardized by ANSI. I can't believe you are stating what you stating when it comes to STL. Come to think of it, I can't believe you're saying this about MFC.Quote:
I've held many contracts in my hand that do not allow the use of STL or MFC, since both are subject to change.
Total nonsense. Again STL is standardized by ANSI.Quote:
At some point the program will need to be compiled again, or MFC will change and then a new bug may be introduced into the system. When your program is required to run for years with out any problem at all, which is the work I do the most, you can not afford the liability of code stopping to work because of an update
OK. The algorithm functions. What do you have to say about them?Quote:
First, there are no algorithm classes, they're all template functions, so unless you are talking about something else then the STL algorithm functions, I'm confused....and if you are talking about the functions, then your statement loses weight.
Incredible. So this is the way you prove your argument -- pretend that maintenance doesn't exist?Quote:
a) well designed code doesn't require maintenance.
No. The programmer is not just "reading C++". They need to understand what the internals of your code is doing. If there is a change to be made, you are compromising the code that has already been written every time a line is removed or added. This is the reason to use standard components.Quote:
b) if you have to train a C++ programmer to read C++, C, or function documentation, then you've hired the wrong guy.
Again, using the "demean the implementation" argument to prove your point. I am currently maintaining various commercial libraries, and commercial systems that make heavy use of the standard libraries. There has yet been a bug attributed to the usage of the standard libraries.Quote:
c) you mean thousands of buggy college programs?
You rely on MSDN? How about books? "The C++ Standard Library" by Nicolai Josuttis, for example.Quote:
d) MSDN does have documentation, its hardly understandable for even the average C++ programmer. Sadly, the technical writer and the programmers who explained it didn't quite understand it, so they used a lot of the original documentation, which is why MSDN is so vague, the original writers didn’t think it would go far enough to need further explanation. That’s why it reads like R&D notes.
I don't know what you're talking about. Are you saying that the programmers who designed the standard libraries are fly-by-night programmers? Just this statement alone invalidates everything you've said so far.Quote:
Guess you never opened one of the header files....
Regards,
Paul McKenzie
Hopefully, you are referring to oktronic's hilarious diatribe against the C++ library.Quote:
Originally posted by souldog
Well I haven't even been programming for a year and a half and
I have enough sense to know what you are saying is BS.
Yes, that's the main point. The current C++ library is standardized as of 1998. It isn't going to change in terms of breaking existing code. If anything, features and more classes / functions are being added, and they will be up for standardization at the next ANSI/ISO committee meeting (I believe this is next year).Quote:
Standardization
But it is interesting that oktronic and others who think like that never doubt that the C-function library may have a bug or be "poorly written" -- they use these functions all the time without a second thought. Their bias is always against the C++ classes and functions.
Regards,
Paul McKenzie
I could not resist joining the discussion :)
Paul does have a point indeed.
I guess, this discussion went into a bit 'personal' mode, though as of what oktronic said, true is that standard headers _are_ sometimes sloppy (e.g., the worst C++ code I ever saw is Windows XP DDK).
Apparently, Microsoft has developed its own programming language called "C++", which includes Hungarian notation, custom types (LPVOID, LPCSTR, BOOL), dummy macros (IN, OUT).
STL way of thinking is not compatible to Microsoft's, so I guess MFC programmers get mad each time they do not see class name beginning with capital C.
STL library was awaited for quite a long time, and was included in the standard in 1998.
Apparently, mixing STL and MFC doesn't give a good result. Though I do it all the time, as I find easier to use STL than digging MSDN (which indeed IS the worst kind of a documentation) to seek what exactly did MS developers mean.
Those who do not like C++, normally should go programming Oberon.
Oberon resembles Pascal, while being totally different in the conception. It is interesting topic to study and discuss, indeed as for present time (2003) it is still inapplicable for the serious tasks.
There are two interesting articles said "Oberon vs C++" and "Oberon2 vs C++".
http://www.modulaware.com/mdlt49.htm
http://www.amadeus-3.com/main_files/oberon2vsCPP.php
Don't bash me, I'm myself a hardcore C++ programmer, but take a look anyway. :)
Thanks,
George.
There is a syndrome called "NIH" (Not Invented Here). Check out this page -- it describes to a tee the mindset of some programmers who are afraid or do not use standard components.
http://c2.com/cgi/wiki?NotInventedHere
Regards,
Paul McKenzie
I've seen it written here by both proponents and opponents of the STL alike, that STL classes aren't supposed to be derived. The proponents of STL see this as an asset, and the opponents, a liability.
I've used MFC a lot, and STL a little, and I've recently written an application which is going to be portable to other OS's so I did the entire back end of the application in STL.
Now, I don't have a lot of experience in STL yet (but I like it), maybe it's my straight-C mindset, and/or maybe I'm nuts, but I did, in fact, derive several of my classes from STL containers. I've never before heard that this is a Bad Thing.
I don't seem to have any problems with this. Everything works as it should. And there are no bugs or leaks or whatever.
Basically what I did was:
And it works.Code:class string_vector : public vector< mystring >
{
public:
string_vector() {}
string_vector( const string_vector& sv ) { ... }
virtual ~string_vector() {}
string_vector operator=( const string_vector& sv ) {...}
string_vector operator += ( mystring str ) { ... }
load( ifstream& in ) { ... }
save( oftream& out ) { ... }
};
It works like a champ.
The load and save functions are the reason I derived the class - I wanted to add serializable functionality to my vector class. And I derived several classes from vector<> which provides various functionalities. (I could have templatized my class, I suppose, but that's beside the point).
It seems like everyone on both sides of the fence do agree that this is not the proper usage of STL.
Why? Is it just bad form? Is there something deeper that I'm missing? I'm not having any problems, and I don't expect to.
Of courseQuote:
Originally posted by Paul McKenzie
Hopefully, you are referring to oktronic's hilarious diatribe against the C++ library.
You say it works like a champ, but if another of your colleagues do this, then you'll be down for the ten count.
Say I want to add more customization to your string_vector. There is nothing stopping me (except maybe a big warning by you in big bold letters) to not derive my own classes and do some polymorphic work.Code:class MyCustomizedStringVector: public string_vector
{
//..
virtual ~MyCustomizedStringVector() { }
virtual int CustomizedFunc();
};
class AnotherCustomizedStringVector : public MyCustomizedStringVector
{
//...
virtual int CustomizedFunc();
};
int main()
{
string_vector *pMyVect;
if ( do_some_customizations )
pMyVect = new MyCustomizedStringVector;
else
pMyVect = new AnotherCustomizedStringVector;
//...
delete pMyVect;
}
Of course, this code leads to undefined behavior since the base class vector<string> does not have a virtual destructor. Even if me, the lowly user of your class, have a virtual destructor in my own class, it would not prevent the undefined behavior from occuring.
So what it all boils down to is that you put (whether you mean to or not) the same restrictions on usage of your class -- you shouldn't derive from it. Sounds familiar, doesn't it?
Again, there is no reason, even in your real-world example, to derive from vector<string>. The only thing you needed to do was to make vector<string> a member instead of deriving.
Regards,
Paul McKenzie
STL objects do not declare virtual destructors so if you derive from an STL object and that object is ever destroyed by a reference to base then your derived destructor never gets called. Also, since users of STL including the library know that you're not supposed to derive from STL objects their is a good chance that someone elses code will copy by value your derived class causing it to be silced. Virtual destructors are not provided by STL because there is a footprint/run-time overhead associated with them. The first time you add a virtual function you get _vtbl overhead regardless of whether or not anyone derives from you but often the compiler can un-virtualize the actual calls. Since the standard does not assume optimizing compilers and one of the standard's principles is "you do not have to pay for what you don't use" - they opt'd not to provide virtual destructors. Exception specifications have a similar overhead issue.Quote:
Why? Is it just bad form? Is there something deeper that I'm missing? I'm not having any problems, and I don't expect to.
In my earlier posts I was not discounting inheritence. Inheritance is the only way to manipulate polymorphic types at run-time and still ensure full type safety. But, many times you do not need the subtype polymorhism - parameterized polymorphism is adaquate. Subtype polymorphism is never faster than parameterized polymorhism. Also, parameterized polymorphism allows (through specialization) generation of optimal code/algorithms for each type while subtyping requires a single common algorithm for all types (I mean the code manipulating the polymorphic type - not internal overridden member functions). Even when optimal code is constructed for each derived type (through virtual member functions and overridden out-of-body functions) there is a cost to the dynamic dispatch.
All of this makes templates (STL included) a much more attractive option to inheritance when efficency matters even if inheritance is easier. Inheritance requires and creates higher cohesion between design concepts - this in turn increases the impact of design changes to the overall system structure which leads often to higher maintenance costs.
None of this might seem like that big a deal - inheritance works why don't we just use it? When timeliness doesn't matter this is probably a workable approach (yet still suboptimal). But I primarly design hard real-time systems. As such, I almost never use inheritance if templating is sufficent. Hense, I would never use MFC if STL is sufficent.
Well, maybe this is not the time or place to ask why, but, why?Quote:
Originally posted by Paul McKenzie
You say it works like a champ, but if another of your colleagues do this, then you'll be down for the ten count.
The code you wrote appeared to me that it should work. I'm not saying I don't believe, you, but... I dunno - maybe I'm just missing something fundamental. If I wanted to do what you described (derive and derive again), I would have attempted it the same way you did up there, and I would have expected it to work properly.
I read your explaination about virtual destructors, and undefined behavior, but I still don't see the why. It still appears to me that this sort of thing should work.
Maybe there's an article or something somewhere that would go into why this won't work?
I thought about that, but in the interest of saving time, I didn't want to write a dozen wrapper functions like push_back, clear, size, et. al. And I didn't want to expose a public vector object.Quote:
Originally posted by Paul McKenzie
Again, there is no reason, even in your real-world example, to derive from vector<string>. The only thing you needed to do was to make vector<string> a member instead of deriving.
Plus, as I said, I'm used to MFC where deriving your classes from the provided library is par for the course. It never dawned on me that I shouldn't derive STL classes until I stumbled across this thread.
Fair enough.Quote:
Originally posted by mclark
STL objects do not declare virtual destructors so if you derive from an STL object and that object is ever destroyed by a reference to base then your derived destructor never gets called.
But suppose my destructor does nothing.
Wouldn't that, then, remove this restriction - at least on my class. It's just another container for my end user (which happens to be me, anyway) and one that behaves exactly as he'd expect, with all the familiar methods and operators, with the additional goodies, I put in there for him - and if he knows better than to inherit from the STL anyway (ha-ha), he shouldn't have any problem not inheriting from my class as well, right?
So when I add that virtual destructor, I basically defeated this purpose - and since my dtor does nothing anyway, I should just 86 it altogether.Quote:
Originally posted by mclark
The first time you add a virtual function you get _vtbl overhead regardless of whether or not anyone derives from you but often the compiler can un-virtualize the actual calls.
Quote:
Originally posted by Paul McKenzie
Code:class MyCustomizedStringVector: public string_vector
{
//..
virtual ~MyCustomizedStringVector() { }
virtual int CustomizedFunc();
};
class AnotherCustomizedStringVector : public MyCustomizedStringVector
{
//...
virtual int CustomizedFunc();
};
int main()
{
string_vector *pMyVect;
if ( do_some_customizations )
pMyVect = new MyCustomizedStringVector;
else
pMyVect = new AnotherCustomizedStringVector;
//...
delete pMyVect;
}
Paul, I don't see a problem here.
A problem will occur only if one tries to do this:
Toxick's class string_vector does have a virtual destructor, and one may derive from it.Code:...
std::vector<std::string> *var = pMyVect;
delete var;
...
Therefore
should be safe to execute.Code:string_vector *pMyVect;
...
pMyVect = new AnotherCustomizedStringVector;
...
delete pMyVect;
The same if you do like this:
As long as you do not cast to hello for deletion (as delete (hello *)worldobject;), it will work fine.Code:struct hello
{
int a,b,c;
};
class world : public hello
{
//...
virtual ~world() {/*... */ }
//...
};
Probably I don't understand something?
Yes, then this is safe as long as you don't add any member data. But since, you've not added any member data and you can't override the inherited functionality (because it's not virtual and you've chosen public inheritance instead of private with forwarding functions - cuz as you said you don't want to write all the forwarding crap) then the only thing you can do is add additional utility functions. But then, those could just as easily been added as normal (non-member) functions that operate on the STL container (unless you're trying to gain access to private members - which are implementation specific and so non-portable anyways).Quote:
But suppose my destructor does nothing.
So, you can get the same effect by using normal functions, which in turn could be templatized and made to work with any vector<T> or container type (ala STL algorithms).
If what you intended to do was somehow restrict the use of the STL type, you cannot do so using public inheritance nor can you stop the user from converting your derived class back to the base - eliminating access to all of your utility functions.
Using the normal function approach may net seem as appealing because it seems less 'OO' but it is a better design.
Well, not to step on mclark's toes, but if you do not define a virtual destructor in your base class, the behavior is undefined if you delete through a base pointer. It may work, it may fail, you don't know. Most of the time, the behavior is to not call the derived class destructor, but again, you don't know.
This is clearly specified in the ANSI/ISO C++ specification. Here is the clause in 5.3.5.5
So there you have it. Your code (or my utilization of your code), leads to undefined behavior. The static type is vector<string>, and the dynamic types are MyCustomizedVectorString, AnotherCustomizedVectorString. Since the static type does not have a virtual destructor, calling delete is undefined behavior.Quote:
In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the
static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual
destructor or the behavior is undefined.
Regards,
Paul McKenzie
Sure you can derive from it. The problem is that the behavior is still undefined. The virtual destructor must be in the top-most base class. The top-most class is vector<string> -- it does not have a virtual destructor.Quote:
Originally posted by gyohng
Paul, I don't see a problem here.
A problem will occur only if one tries to do this:
Toxick's class string_vector does have a virtual destructor, and one may derive from it.Code:...
std::vector<std::string> *var = pMyVect;
delete var;
...
You are using what you think should work, instead of investigating what the rules are of C++ (which I specified in my previous post in clause 5.3.5.5).
Regards,
Paul McKenzie
I stand corrected - my bad for not checking before I spoke. I'm a lot more careful with my code than with my words. :)Quote:
Originally posted by Paul McKenzie
Well, not to step on mclark's toes, but if you do not define a virtual destructor in your base class, the behavior is undefined if you delete through a base pointer.
No, I didn't. The only thing I added was 2 operators, and serialization functions.Quote:
Originally posted by mclark
Yes, then this is safe as long as you don't add any member data.
Which is exactly what I did. So it sounds to me that I'm pretty much in business with my classes as they are, and anyone who uses them in the future should not run into any snags along the way.Quote:
Originally posted by mclark
But since, you've not added any member data and you can't override the inherited functionality (because it's not virtual and you've chosen public inheritance instead of private with forwarding functions - cuz as you said you don't want to write all the forwarding crap) then the only thing you can do is add additional utility functions.
Honestly, after reading all you wrote, the fact that my classes work the way they're intended is dumb luck - and not by any design of my own. :)
Not really. I just want to use an object that looks, smells, acts, and IS a vector - but one to which I can pass an fstream object for loading and saving of the vector elements. (And one that I can use += for appending new elements.)Quote:
Originally posted by mclark
But then, those could just as easily been added as normal (non-member) functions that operate on the STL container (unless you're trying to gain access to private members - which are implementation specific and so non-portable anyways).
I know I could do all that through external (or existing) functions, and being a C programmer at heart, that was my first instinct. But I'm trying to blossom into an OO programmer, and I thought that was what OO was all about. Reusing stuff that's already built.
I restricted the use of the STL type, not a whit.Quote:
Originally posted by mclark
If what you intended to do was somehow restrict the use of the STL type, you cannot do so using public inheritance nor can you stop the user from converting your derived class back to the base - eliminating access to all of your utility functions.
In fact, the very reason I derived from the STL type was because I wanted to use all the functionality that it currently contains. However, if the end user wants to cut himself off at the knees and cast up to a class that has the original functionality, that's fine by me. My new methods are not vital at all to the behavior of the vector itself - they are merely quick and painless ways of building in the functionality of serializing object data.
Well, in my case it is... So, suppose I go all the way back to my original code up there, and delete the line: virtual ~string_vector() {}Quote:
Originally posted by Paul McKenzie
Most of the time, the behavior is to not call the derived class destructor, but again, you don't know.
Because my dtor is empty anyway. It adds or removes not a thing.
One of the principles of good OO is that an obect's interface be minimal. If an operation or algorithm can be implemented in terms of already existing public interfaces; then the new operation or algorithm should itself NOT be a member but instead a stand-alone function. In the long run this makes a class heirarchy much more extensible. The approach you took is understandable - but not correct. It is often refered to as a 'fat' interface.Quote:
Originally posted by Toxick
But I'm trying to blossom into an OO programmer, and I thought that was what OO was all about. Reusing stuff that's already built.
If two operations are circularly dependent, then the simpler of the two (most generalizable to subtyping) should be chosen as an interface member. If neither is widely generalizable, then neither should be members. Instead, one should be a 'friend' and the other implemented in terms of the friend.
Doing otherwise means that the heirarchy is self-limiting. Defining subtypes (IS-A relationships) is artifically restricted to concepts who are both IS-A and operation-applicable.
Good OO often means knowing what's not a object.
Paul,
The clause says that it is safe. And your code will work.
Indeed, static type pointer, which is string_vector, has VIRTUAL DESTRUCTOR.
We are doing:
delete ( string_vector * ) obj ;
where
class string_vector : public vector<string>
{
...
----> virtual ~string_vector() { } <----
...
}
if obj has type MyCustomizedStringVector* , then
- the dynamic type is MyCustomizedStringVector
- the static type is string_vector
and the clause is correct, because MyCustomizedStringVector and string_vector BOTH do have virtual destructors.
As long as code is guaranteed not to delete by std::vector<std::string>* type, then the execution is guaranteed to be proper in this case.
Again, as long as we only delete by ANY type that has virtual destructor (meant as static (compile-time) type in the Standard clause), the delete operator is guaranteed to work properly.
Clause does not say "all of the chain should have virtual destructors", clause says "type we delete by should be somewhere in the chain BEFORE the runtime type, and it should have virtual destructor". Clause does not mean the base class of the operand static pointer type should have virtual destructor. It only says that the operand static type itself should have virtual destructor, and not the parent of the operand static type.
To avoid misunderstanding, here is it again:
static_type *obj = new dynamic_type ( ) ;
...
delete obj ;
Thanks,
George.
But it still doesn't take away from the fact that deleting string_vector through a pointer-to-base is undefined behavior. In fact, there is no rule at all in ANSI C++ that states that "if you have no members defined, you're OK if you delete your object". Undefined behavior means just that -- undefined. Whether or not your class is empty, it makes no difference.Quote:
Originally posted by Toxick
Well, in my case it is... So, suppose I go all the way back to my original code up there, and delete the line: virtual ~string_vector() {}
Because my dtor is empty anyway. It adds or removes not a thing.
Don't be surprised one day when your code crashes, and you'll be scratching your head as to why the crash occurs. It's the same type of situation where a C++ programmer uses memcpy() for a non-POD object, and then suddenly when they port their program or upgrade the compiler, their program ceases to work. It happened to me a month ago -- a programmer used memcpy() to initialize a struct that contained a std::string, and the program "worked" under VC 6.0. When ported to C++ builder (we need to create libraries for both compilers), the code crashed.
Regards,
Paul McKenzie
vector<string>'s dtor won't be called.
This makes no sense to me.Quote:
Originally posted by mclark
One of the principles of good OO is that an obect's interface be minimal. If an operation or algorithm can be implemented in terms of already existing public interfaces; then the new operation or algorithm should itself NOT be a member but instead a stand-alone function.
The entire reason that I decided on a paradigm shift from straight C to C++ was because I can do something like take a vector, add my own crap on it, tint the windows, shine the tires, superbass the radio, and reuse my class in a hundred different programs.
However, it looks like you're saying here that the best method of accomplishing my task is to put a function in my programs like:
load( vector<whatever> myvec ) {...}
and if I want to use it in a hundred programs, I'll have to "Ctrl+C - Ctrl+V" a hundred times.
I did that in C. That's the crap I'm trying to get away from.
On the other hand, if I make a "serial_vector<whatever>" class which derives from vector and add a load function to it - I can write it once, and just include the file in my hundred programs, and it works across the board.
Fat interface or not. This just Makes Sense to me.
Now I understand that if it don't work - it don't work, and I can whine till I'm blue in the face, and it's not going to change it, but it certainly seems to me that the paradigm is contradicted by it's very own standard.
Sigh. You are totally forgetting the fact that the string_vector class is derived from vector<string>. The static type is vector<string>. It has no virtual destructor. Therefore the behavior is undefined. Doesn't vector<string> have to be destroyed? How can you guarantee this if vector<string>'s destructor is not virtual?Quote:
Originally posted by gyohng
Paul,
The clause says that it is safe. And your code will work.
Indeed, static type pointer, which is string_vector, has VIRTUAL DESTRUCTOR.
Plain and simple, you're just wrong. If it were as simple as just creating your own class that has a virtual destructor, then these problems wouldn't exist.
Regards,
Paul McKenzie
Well, I've accepted the fact that the way I wrote it is wrong. I've not argued with you and said, "You're wrong - it WILL SO work". I'm asking WHY it's wrong. That's why I came in here. I was hoping to find a loophole where I COULD derive my classes from the STL classes if I followed a certain protocol, but it appears that ain't gonna happen no matter what.Quote:
Originally posted by Paul McKenzie
Don't be surprised one day when your code crashes, and you'll be scratching your head as to why the crash occurs.
And now, I'm trying to figure out what's the point of using an OO library or language if you can't (or shouldn't) use OO techniques. (like inheritance).
Which, I suppose, puts me in the position of the original poster, and I don't think we need to hash that out again. Or at least I don't feel like getting involved with hashing it out.
Anyway, I see that what I was doing is wrong - I also now see why it's wrong.
But I don't much like it.
Run this, please:Quote:
Originally posted by AvDav
vector<string>'s dtor won't be called.
Code:#include <iostream>
using namespace std;
class class1
{
public:
~class1() { cout << "~class1\n"; }
};
class class2 : public class1
{
public:
~class2() { cout << "~class2\n"; }
};
class class3 : public class2
{
public:
virtual ~class3() { cout << "~class3\n"; }
};
class class4 : public class3
{
public:
virtual ~class4() { cout << "~class4\n"; }
};
class class5 : public class4
{
public:
virtual ~class5() { cout << "~class5\n"; }
};
int main()
{
class3 *obj = new class5();
delete obj;
return 0;
}
I believe it is exactly like I said before. See my previous post with class1...class5 examples.Quote:
Originally posted by Paul McKenzie
Plain and simple, you're just wrong. If it were as simple as just creating your own class that has a virtual destructor, then these problems wouldn't exist.
I _really_ _really_ think, that by "static type", the standard guys mean
THE POINTER TYPE THAT IS PASSED TO DELETE
and NOT
THE TOPMOST BASE CLASS POINTER TYPE.
I may be wrong, but well - it works. I added printf into vector type destructor and it gets called indeed.
delete (derived_from_vector_but_with_virtual_destructor *) obj ; // works
delete ( vector<string> *) obj ; // doesn't work
where type of obj is descendant of derived_from_vector_but_with_virtual_destructor
But this is just what I'm saying all the time.
Thanks,
George.
Toxick,
Suggestions were given to use a wrapper to enclose basic_string.
However, you have rejected this method.
The functionality that you are wanting to add must go
somewhere. If you could derive from basic_string, you would
have the functionality there.
Or you could write the wrapper class and the functionality would
be there.
In this case, it has to reside somewhere where you don't want it
to go. That is a result of tradeoffs taken during the design of STL.
There are many examples of classes which cannot be inherited
from. This is by design. Does this mean that these classes are
not OO??
By your definition, these classes are not OO.
You are determined to use the STL functionality in a way that it
were not meant to be used. In fact, in a way that it has been
designed to not be used.
Inheritance can be accomplished in several ways. MClark andQuote:
And now, I'm trying to figure out what's the point of using an OO library or language if you can't (or shouldn't) use OO techniques. (like inheritance).
Paul McKensie have given options on how to do this.
Showing code does not prove your point. I can show code where calling "delete" instead of "delete[]" works when I use operator new[]. It doesn't make it correct.Quote:
Originally posted by gyohng
Run this, please:
The class2 destructor is non-virtual, and you derive from class2. It makes no difference if you derive a class from a class from a class. The base class still has no virtual destructor, therefore the behavior is undefind.
Regards,
Paul McKenzie
Please, read the standard more carefully.
The class1...class5 code is written per standard, I have checked this.
For now, I stop arguing, as you insist on your point not reading my posts carefully.
The problem is that you misunderstand the "static type" definition in the clause you have quoted.
Not to offend you, I really beg you to re-read my posts carefully. I did few editions, so that the text will be easier to understand.
Quote:
Originally posted by Paul McKenzie
Showing code does not prove your point. I can show code where calling "delete" instead of "delete[]" works when I use operator new[]. It doesn't make it correct.
The class2 destructor is non-virtual, and you derive from class2. It makes no difference if you derive a class from a class from a class. The base class still has no virtual destructor, therefore the behavior is undefind.
Regards,
Paul McKenzie
I understand your frustration but Objects are not panacea and neither is OO. C++ as a language, recongnizes that there are tradeoffs when using objects and inheritance. If there were none, then objects would have subplanted the traditional C language constructs within the language itself. C++ as a langague would mandate that all things are inheritable from and all things inherit from a common base. If this style is most appealing to you, there are other OO languages besides C++ that do enforce this structure from within the language.Quote:
Originally posted by Toxick
Fat interface or not. This just Makes Sense to me.
Now I understand that if it don't work - it don't work, and I can whine till I'm blue in the face, and it's not going to change it, but it certainly seems to me that the paradigm is contradicted by it's very own standard.
But for C++, struggling to use only this approach and not understanding why it is not possible reflects a niave grasp of how OO concepts relate to language constructs.
You may not like it but it is the excepted best-practice for OO within the language of C++.