Thread: MC++/portability

  1. #1
    Registered User
    Join Date
    Jan 2008
    Posts
    24

    MC++/portability

    Because I was introduced to C++ through MSVS.NET, I quickly got used to the managed extensions before learning standard C++. Now, I'm having to go back and relearn a lot of things so that my code is (somewhat) portable. Anyway, I've read that the best rule of thumb for standard C++ memory allocation, is that for every new, you should have a matching delete, but how does this apply to inter-class instantiation? For example, if I instantiate an object within a class's constructor, would the best place to delete it be within the destructor? Is this even necessary (does the destructor do this for me)? Should I create a method for this purpose instead?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    For example, if I instantiate an object within a class's constructor, would the best place to delete it be within the destructor?
    If the object is local to the constructor, then of course not. If the object is a member of the class, then it depends. For example, if the member manages its own memory, then you have nothing to do concerning it in the destructor. On the other hand, if you are talking about a pointer member for which the object owns the object pointed to, then using new/new[] in the constructor and delete/delete[] in the destructor probably makes sense.

    I note that this is related to the RAII idiom, which basically involves associating the lifetime of a resource with that of an object.

    Is this even necessary (does the destructor do this for me)?
    The destructor does destroy the member objects, but the problem in the case of pointers is that it would destroy the pointers but not free what the pointers point to.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jan 2008
    Posts
    24
    Quote Originally Posted by laserlight View Post
    If the object is local to the constructor, then of course not. If the object is a member of the class, then it depends. For example, if the member manages its own memory, then you have nothing to do concerning it in the destructor. On the other hand, if you are talking about a pointer member for which the object owns the object pointed to, then using new/new[] in the constructor and delete/delete[] in the destructor probably makes sense.

    I note that this is related to the RAII idiom, which basically involves associating the lifetime of a resource with that of an object.


    The destructor does destroy the member objects, but the problem in the case of pointers is that it would destroy the pointers but not free what the pointers point to.
    If I understand correctly, because the object owns the object being pointed to, but doesn't manage the memory (the member is just a pointer), then I have to delete it somewhere, and the destructor would be the best choice?

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If the constructor allocates the memory, then the typical best situation is to free it in the destructor.
    Or you can use RAII-type class to manage memory, such as smart pointers.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by drrcknlsn View Post
    If I understand correctly, because the object owns the object being pointed to, but doesn't manage the memory (the member is just a pointer), then I have to delete it somewhere, and the destructor would be the best choice?
    Yes - it certainly has to be deleted somewhere, and most often, the destructor is the right place. If you don't do it in the destructor, you should make the destructor check that the pointer is NULL when you get there to ensure that it HAS been deleted.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Jan 2008
    Posts
    24
    Thanks guys.

    Incidentally, while I have your attention, is there a better reference for reading up on const-correctness? I've read the article on this site and a few other brief ones I found on Google, but I'm still pretty confused.

    How would I make the following methods const-correct? Or did I do it right (doubt it)?

    Code:
    class Node
    {
    public:
    
        //  get
        Node *next () const { return mNext; }
        std::string data () const { return mData; }
    
        //  set
        void next ( Node *pNewNext ) { mNext = pNewNext; }
        void data ( const std::string &rNewData ) { mData.assign ( rNewData ); }
    
    private:
    
        Node *mNext;
        std::string data;
    };

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Set next should also take const.
    The const is pretty correct, only you've defined next/data twice, both for get and set.
    Const correctness isn't difficult, however. Const just means you won't change the data.
    Const on a function means the function won't modify any global or member variables (but local variables are fine).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Don't know about any good reference, but:
    Code:
    class Node
    {
    public:
    
        //  get
        const Node *next () const { return mNext; }
        std::string data () const { return mData; }
    
        //  set
        void next ( const Node *pNewNext ) { mNext = pNewNext; }
        void data ( const std::string &rNewData ) { mData.assign ( rNewData ); }
    
    private:
    
        Node *mNext;
        std::string data;
    };
    I personally don't like the style of using exactly the same names for getter/setter functions - I think it makes it hard to read the code that way - but that's just my opinion, and if you already have a lot of code [or have been told to do so by someone who is "judging" your code, such as your boss or a teacher], then please don't change it just because I say so.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by matsp View Post
    I personally don't like the style of using exactly the same names for getter/setter functions - I think it makes it hard to read the code that way
    I agree with that. I like when functions explicitly tell what they're doing, so they should be named GetNext/SetNext and GetData/SetData (or something similar).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Jan 2008
    Posts
    24
    Why does 'next' need to return a const, but not 'data'?

    And does 'const Node *' translate to 'a constant pointer to a Node object' or 'a pointer to a constant Node object'? From what I've read, 'const' applies to whatever is directly to the left of it, or the right if nothing is left of it, so would 'Node * const' act differently?

    As far as the naming convention goes, I'd rather use the following:

    Code:
        //  get
        const Node *next () const { return mNext; }
        const std::string &data () const { return mData; }
    
        //  set
        Node *rNext () { return mNext; }
        std::string &rData () { return mData; }
    ...because I like the idea of letting the object handle operation. The only problem is that it requires me to wrap the primitive types in order to do bounds checking.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by drrcknlsn View Post
    Why does 'next' need to return a const, but not 'data'?
    In your case, it returns by value so a new copy is created. You don't need to protect the data then. The string returned can be modified at will without modifying the original. IF you returned a reference, however, it should be const.

    And does 'const Node *' translate to 'a constant pointer to a Node object' or 'a pointer to a constant Node object'? From what I've read, 'const' applies to whatever is directly to the left of it, or the right if nothing is left of it, so would 'Node * const' act differently?
    So, here's how I look at it:
    (type)* (variable);
    So anything in the type section is the type of the pointer and anything in the variable section applies to the variable itself.
    So,
    const Node* p is a pointer to a constant Node object - you can't modify the object pointed to by the pointer.
    Node* const p is a constant pointer to a Node object. You can't change the variable, but you can change the object it points to.
    As far as the naming convention goes, I'd rather use the following:

    Code:
        //  get
        const Node *next () const { return mNext; }
        const std::string &data () const { return mData; }
    
        //  set
        Node *rNext () { return mNext; }
        std::string &rData () { return mData; }
    ...because I like the idea of letting the object handle operation. The only problem is that it requires me to wrap the primitive types in order to do bounds checking.
    That's even more confusing.
    If you want the object itself to do the operations, or in other words, want to do the operations on the objects themselves, you should make them public instead. There's no use in writing a wrapper just for that.
    If you want a set/get approach, then name the function appropriately.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by drrcknlsn View Post
    Why does 'next' need to return a const, but not 'data'?
    Because you are returning something INSIDE your class with "next", rather than a copy of something inside your class with "data".

    And does 'const Node *' translate to 'a constant pointer to a Node object' or 'a pointer to a constant Node object'? From what I've read, 'const' applies to whatever is directly to the left of it, or the right if nothing is left of it, so would 'Node * const' act differently?
    Yes, they are different - in the first case, you say that you have a constant pointer to node, in the second case you say you have a pointer to a constant node - which certainly isn't the case for your setter function - it may be true for the getter function - try it and see if it still works. One of the good things about const is that it's the compiler that decides if it works or not, so if it compiles correctly, it's "correct".

    As far as the naming convention goes, I'd rather use the following:

    Code:
        //  get
        const Node *next () const { return mNext; }
        const std::string &data () const { return mData; }
    
        //  set
        Node *rNext () { return mNext; }
        std::string &rData () { return mData; }
    ...because I like the idea of letting the object handle operation. The only problem is that it requires me to wrap the primitive types in order to do bounds checking.
    As long as you are happy with that... Just remember that easy to read code is easy to work with. Our company standard is "setters are called SetSomething()" and getters are called "Something()".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Jan 2008
    Posts
    24
    OK... I modified what you suggested, but now it's spitting out "error C2440: '=' : cannot convert from 'const Node *' to 'Node *'

    Code:
    	void	setNext		( const Node *		pNewNext		) { mpNext				= pNewNext;			}
    
    //  snip snip
    
    	Node *	mpNext;
    Oh... and here's it's usage:

    Code:
    Node *test1 = new Node ();
    Node *test2 = new Node ();
    
    //  snip snip
    
    test1->setNext ( test2 );
    Last edited by drrcknlsn; 01-25-2008 at 04:59 PM.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Hoo-my. Doesn't look like it likes that, huh? You're going to have to remove the const from setNext to make it work.
    Haha... didn't think of that. Of course, if it assigns the variable to the class member function which isn't const, of course the set function can't take a const pointer since the class can modify it later.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And which line do you get that error on? Where you are calling setNext() or the line where you define the function setNext()?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Looking for sample MC test questions for a job
    By garp in forum C Programming
    Replies: 2
    Last Post: 09-29-2003, 05:30 AM
  2. MC Hammer
    By Zewu in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 07-06-2003, 05:17 PM
  3. Recursion = headache;
    By RoD in forum C++ Programming
    Replies: 9
    Last Post: 12-20-2002, 09:34 PM