CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 7 of 19 FirstFirst ... 4567891017 ... LastLast
Results 91 to 105 of 280
  1. #91
    Join Date
    Jun 2003
    Location
    Armenia, Yerevan
    Posts
    720
    vector<string>'s dtor won't be called.

  2. #92
    Join Date
    Sep 2002
    Location
    Tucson, Arizona
    Posts
    26
    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.
    This makes no sense to me.

    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.
    No animals were harmed in the transmission of this message. However, a good number of electrons were somewhat inconvenienced.

  3. #93
    Join Date
    Apr 1999
    Posts
    27,449
    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.
    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?

    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

  4. #94
    Join Date
    Sep 2002
    Location
    Tucson, Arizona
    Posts
    26
    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.
    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.

    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.
    No animals were harmed in the transmission of this message. However, a good number of electrons were somewhat inconvenienced.

  5. #95
    Join Date
    Nov 2003
    Posts
    7
    Originally posted by AvDav
    vector<string>'s dtor won't be called.
    Run this, please:

    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;
    }
    http://www.yohng.com/

  6. #96
    Join Date
    Nov 2003
    Posts
    7
    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 believe it is exactly like I said before. See my previous post with class1...class5 examples.

    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.
    Last edited by gyohng; November 21st, 2003 at 02:15 PM.
    http://www.yohng.com/

  7. #97
    Join Date
    Aug 2001
    Location
    Texas
    Posts
    645
    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.

    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).
    Inheritance can be accomplished in several ways. MClark and
    Paul McKensie have given options on how to do this.

  8. #98
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by gyohng
    Run this, please:
    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

  9. #99
    Join Date
    Nov 2003
    Posts
    7
    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.

    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
    Last edited by gyohng; November 21st, 2003 at 02:27 PM.
    http://www.yohng.com/

  10. #100
    Join Date
    Nov 2003
    Location
    Pasadena, CA
    Posts
    48
    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.
    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.

    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++.
    The views expressed are those of the author and do not reflect any position taken by the Goverment of the United States of America, National Aeronautics and Space Administration (NASA), Jet Propulsion Laboratory (JPL), or California Institute of Technology (CalTech)

  11. #101
    Join Date
    Sep 2002
    Location
    Tucson, Arizona
    Posts
    26
    Originally posted by cvogt61457
    Suggestions were given to use a wrapper to enclose basic_string.
    However, you have rejected this method.
    I have not rejected this method. I would, however, like to ensure that the way I did it is completely and totally wrong before I re-write thousands of lines of code.

    Two people, both of which seem to know a great deal more than I, are currently presenting arguments one of which says the way I did it is ok, the other says I'm not. Regardless of who is correct, I have not rejected anything out of hand.



    And my vector<string> class is not using a basic_string. It's using my own base serial_string class which is a wrapper around a simple char array but has a lot of the basic_string functions. As well as serializing functions.

    Originally posted by cvogt61457
    The functionality that you are wanting to add must go
    somewhere. If you could derive from basic_string, you would
    have the functionality there.
    It does. All my string_vector class does is loop through each element it holds and and calls the save (or load) method of each individual serial_string object.

    Yeah - I know - this is easily done from an external method.

    Originally posted by cvogt61457
    Or you could write the wrapper class and the functionality would
    be there.
    Again, I want to ensure that I really screwed up before I engage in such a re-coding project.

    Originally posted by cvogt61457
    By your definition, these classes are not OO.
    Not by my definition. I learned that OO consisted of "Encapsulation", "Inheritance" and "Polymorphism". These three fundamentals were driven into my brain by every book, document and person that I consulted about OO programming.

    And now the standard says, "To **** with it!" Design or no -it makes no sense to me to have the standard contradict the paradigm - indeed, to deliberately undermine the paradigm.

    But this is useless whining. I'm not here to argue about what it should be.

    Originally posted by cvogt61457
    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.
    Unclench, Sparky.

    I'm not determined to do anything but ensure the survival of my application.

    If that means rewriting 2000 lines of code, then so be it - but certainly you can see my interest in trying to avoid rewriting 2000 lines of code.


    People are waiting for me to finish here.

    This will cause a delay I don't want.
    No animals were harmed in the transmission of this message. However, a good number of electrons were somewhat inconvenienced.

  12. #102
    Join Date
    Nov 2003
    Location
    Pasadena, CA
    Posts
    48
    Originally posted by gyohng
    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.
    Gyohng,

    I've read and understand your code - and your point, but I am still not confident that you are correct (but you may be). The crux of the problem is interpreting the standard.

    Your claim is that since the compiler will do the destruction of Class5 as a pointer-to a Class3 and the compiler knows the Class3's destructor is virtual - that it in fact will perform a virtual method call invoking Class5's destructor instead of Class3's.

    You claim that in your interpretation of the standard this will always be safe - since the object is always destroyed via a base with as virtual destructor.

    Paul's claim is that by the mere fact that a non-virtual destructor exists in an ancestor of Class5 (Class1) that the standard deems the behavior as undefined regardless of the fact that Class5 is destroyed via an intermediary base with a virtual destructor.

    The correct answer will lie in the standard where it describes the call ordering and rules of destuctor invocation. I leave the dissecting of the standard to you two.
    The views expressed are those of the author and do not reflect any position taken by the Goverment of the United States of America, National Aeronautics and Space Administration (NASA), Jet Propulsion Laboratory (JPL), or California Institute of Technology (CalTech)

  13. #103
    Join Date
    Sep 2002
    Location
    Tucson, Arizona
    Posts
    26
    Originally posted by mclark
    I understand your frustration but Objects are not panacea and neither is OO.
    No you don't, or you would not have written this:

    Originally posted by mclark
    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.
    As I've said before - I'm not struggling to use this approach. I flat out used it. If it's wrong, it's wrong - I'll rewrite the code. But my frustration lies within the fact that I have to rewrite a butt-load of code - not because STL doesn't conform to what I believe OOP should be.

    And I, by God, wanna be sure that the code is irrevocably, inexorably broken before I break down and rewrite a good portion of my application.

    Originally posted by mclark
    You may not like it but it is the excepted best-practice for OO within the language of C++.

    I didn't come here to argue about what I like - although it may be starting to sound that way. I came here to find out what it is - and ensure that I don't do it again.


    All the complaining I'm doing is just gravy
    No animals were harmed in the transmission of this message. However, a good number of electrons were somewhat inconvenienced.

  14. #104
    Join Date
    Nov 2003
    Posts
    7
    mclark,

    I have just checked the code under GNU C++ 2.95, 3.0, VC6, VC7, Intel C++ v7 compiler, Borland C++Builder6 - every compiler seems to handle the case properly (as per my interpretation).

    Moreover, I have altered std::vector sources to include printf in the destructor and tested on Paul's example - seems to work fine either.

    As for paul's reference for copying std::string with memcpy - it is completely invalid and was pure luck to work, because std::string does not contain string data inside. It contains pointer to string data. And I guess the code succeeded once only due the fact that some std::string implementations are reference-counting.

    Thanks,
    George.

    Originally posted by mclark
    Gyohng,

    I've read and understand your code - and your point, but I am still not confident that you are correct (but you may be). The crux of the problem is interpreting the standard.

    Your claim is that since the compiler will do the destruction of Class5 as a pointer-to a Class3 and the compiler knows the Class3's destructor is virtual - that it in fact will perform a virtual method call invoking Class5's destructor instead of Class3's.

    You claim that in your interpretation of the standard this will always be safe - since the object is always destroyed via a base with as virtual destructor.

    Paul's claim is that by the mere fact that a non-virtual destructor exists in an ancestor of Class5 (Class1) that the standard deems the behavior as undefined regardless of the fact that Class5 is destroyed via an intermediary base with a virtual destructor.

    The correct answer will lie in the standard where it describes the call ordering and rules of destuctor invocation. I leave the dissecting of the standard to you two.
    Last edited by gyohng; November 21st, 2003 at 02:59 PM.
    http://www.yohng.com/

  15. #105
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245
    Originally posted by gyohng
    I have just checked the code under GNU C++ 2.95, 3.0, VC6, VC7, Intel C++ v7 compiler, Borland C++Builder6 - every compiler seems to handle the case properly (as per my interpretation).

    Moreover, I have altered std::vector sources to include printf in the destructor and tested on Paul's example - seems to work fine either.
    That does not mean that it agrees with the C++ standard. On every one of the platforms you mentioned above, sizeof(short) equals 2. But that is not spelled out in the standard. In fact the standard says sizeof(short) must be greater than or equal to sizeof(char). That means sizeof(short) can be 1 according to the standard. I'm not saying that your code disagrees with the standard. I'm just saying that your argument for standard compliance is invalid. Like mclark said, I'll let you and Paul hash out what is really in the standard (since I don't have a copy).

    - Kevin

Page 7 of 19 FirstFirst ... 4567891017 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured