Thread: A homework problem about C++ (Pointer)

  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    77

    A homework problem about C++ (Pointer)

    I have a problem about how to use a pointer to modify this program.
    At first my adviser asked me to change "int value;" to "int* value;" in case to make the vaule be reference. However, I don't really understand how to refactor the program structure in case to make it be a pointer.
    Also, • I must make my class “pointer safe” by adding the following
    o Copy constructor
    o Destructor

    Does someone can give me some advices? I am not going to get an exactly program by u guys, but can u guys give me some good ideas.

    I would really appericate about it.;


    Code:
    // Integer.h
    #ifndef INTEGER_H
    #define INTEGER_H
    
    class Integer
    {
         public:
               Integer() {value = 0;}
               Integer( int intVal );
    
               int getInteger() const;
               void setInteger( int newInteger );
               Integer& operator=( const Integer& rhInteger );
         
         private:
               int value; // This line will be removed…
               // int* value; // and replaced with this one…
               // NOTE: You will only use ONE attribute
    };
    
    #endif
    
    
    // Integer.cpp
    #include “integer.h”
    
    Integer::Integer( int intVal )
    {
        value = intVal;
    }
    
    
    
    
    int Integer::getInteger() const
    {
        return value; 
    }
    
    void Integer::setInteger( int newInteger )
    {
        value = newInteger;
    }
    
    Integer& Integer::operator=( const Integer& rhInt )
    {
        value = rhInt.value;
        return *this;
    }
     
    // IntegerTest.cpp
    #include <iostream>
    #include <cstdlib>
    #include “integer.h”
    
    using namespace std;
    
    void displayInteger( char* str, Integer intObj )
          {
                 cout << str << “ is “ << intObj.getInteger() << endl;
          }
    
    int main( int argc, char* argv[] )
    {
        Integer intVal1;
        Integer intVal2(10);
    
        displayInteger( “intVal1”, intVal1 );
        displayInteger( “intVal2”, intVal2 );
        
        intVal1 = intVal2;
    
        displayInteger( “intVal1”, intVal1 );
    
        return EXIT_SUCCESS;
    }

  2. #2
    People Love Me
    Join Date
    Jan 2003
    Posts
    412
    It looks fine to me. But to create a pointer that points to an object (and can access all the class data via dereferencing), use this syntax:

    Code:
    Cat *Frisky = new Cat(/*Any parameters for constructor*/);
    //Use the object all you need, for example:
    (*Frisky).Meow(); //OR....
    Frisky->Meow();
    //When we don't need the object anymore,
    delete Frisky;
    This way, you can dynamically allocate and de-allocate memory for your objects.

  3. #3
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    The problem is that in order for your pointer to point to something usefull you have to call new. This needs to be in your constructor, so that you can be sure that the pointer never takes on an invalid value. This alone is not difficult, however every call to new must be paired with one, and only one, call to delete, otherwise you get what is known as a memory leak. The only reasonable place to do this is in the destructor. However the default copy constructor and default assignment operator simply copy the address that the pointer points to. This means that you now have two objects that have pointers to the same location, whose desructors will eventually be called. The safest, easiest, and slowest and most wasetfull stratigy to deal with this is called "deep copy". In this case we simply call new every time the copy constructor is invoked. Assignment is tricky only in the case of self assignment.
    Code:
    // check for self assignment
    Integer& Integer::operator=( const Integer& rhInt ) {
        if(rhInt.value != value) { // compare addresses, not values
            delete value;
            value = new int(*(rhInt.value));
        }
        return *this;
    }
    // call new before calling delete (safe for self assignment)
    Integer& Integer::operator=( const Integer& rhInt ) {
    // do not dereference a null pointer, consider a null pointer 
    // to be a  deep copy of a null pointer.  
        int *new_int = rhInt.value?new(*(rhInt.value)):0;
        delete value;
        value = new_int;
        return *this;
    }
    // explicitly call copy ctor, swap with copy
    Integer& Integer::operator=( const Integer& rhInt ) {
        Integer copy(rhInt); // deep copy
        int *temp = value;  // remember what we used to own
        value = copy.value; // steal the new deep copy
        copy.value = temp; // give copy responsibilty for cleaning up our mess
        return *this; // copy's dtor is called here
    }
    // It's not a bad idea to give any class with a pointer a swap method
    void Integer::swap(Integer &other) {
        int *temp = value;
        value = other.value;
        other.value = temp;
    }
    // then we can simplify deep assignment
    Integer& operator = (Integer copy) {swap(copy); return *this;}

  4. #4
    Registered User
    Join Date
    Mar 2005
    Posts
    77
    thanks all^^

  5. #5
    Registered User
    Join Date
    Mar 2005
    Posts
    77

    Cool

    So, Should I use this part to switch with my old
    Code:
     
    Integer& Interger::operator=( const Interger& rhInt)
    {
             value = rhInt.value;
             return *this;
    }
    to that one

    Code:
    // call new before calling delete (safe for self assignment)
    Integer& Integer::operator=( const Integer& rhInt ) {
    // do not dereference a null pointer, consider a null pointer 
    // to be a  deep copy of a null pointer.  
        int *new_int = rhInt.value?new(*(rhInt.value)):0;
        delete value;
        value = new_int;
        return *this;
    but. what is it?

    Code:
     
    int *new_int = rhInt.value?new(*(rhInt.value)):0;

  6. #6
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    The ternary operator is:
    boolean? yes : no

    So, to break this down:
    if rhInt.value is true (i.e. non-zero or non-null), then the result is new(*(rhInt.value)); if it's false (zero or NULL), then the result is 0.

    Except, I think, new(*(rhInt.value)) should be:
    new int(*(rhInt.value))

    **P.S.
    For the most part, the changes will consist of:
    -use new to initialize the int* in the constructor/copy constructor.
    -use delete to destroy free the memory the int* is pointing to in the destructor.
    -use (*value) instead of value, since it's now a pointer to an int rather than an int itself.
    Last edited by Hunter2; 03-13-2005 at 05:30 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #7
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    Code:
        if(rhInt.value == 0) {
    //  the right hand side points to nothing, so that we are equal later we should point
    //  to nothing therefore we set the pointer we are going to be using to nothing/null
            new_int = 0;
        } else {
    //  The right hand side points to something, we want to point to a different something 
    //  that is a copy of the other something therefor we set new_int to point to the result
    //  of calling new.
        new_int = new  // A new something but a new what?
                        int   // the type of the new something, we need to call a constructor
                           (  // what constructor?
                            * // we are dereferencing somthing this has type int. thus a
                              // construtor that takes a single value of type int, 
                              // int's copy ctor int::int(const int &other);
                              (rhInt.value) // what we are dereferencing, this has type
                                            // pointer to int
                      );
        }
    it's just shorter the other way.
    On edit: and Hunters version will actually work.
    Last edited by grib; 03-13-2005 at 05:45 PM. Reason: font dammage, acknowlage typo

  8. #8
    Registered User
    Join Date
    Jan 2003
    Posts
    311

    Wink

    Quote Originally Posted by Hunter2
    Except, I think, new(*(rhInt.value)) should be:
    new int(*(rhInt.value))
    The above is clearly an attempt to avoid actually doing the original posters homework. I will go hide now.

  9. #9
    Registered User
    Join Date
    Mar 2005
    Posts
    77
    thanks
    let me try it again.

  10. #10
    Registered User
    Join Date
    Mar 2005
    Posts
    77
    However, i still not understand how i modify the program.

    Which part i should modify? .ccp or .h?
    thanks

  11. #11
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Probably both. Wherever you do anything concerning the variable you're changing, you'll need to make slight modifications..
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A problem with pointer initialization
    By zyklon in forum C Programming
    Replies: 5
    Last Post: 01-17-2009, 12:42 PM
  2. Problem with function's pointer!
    By Tirania in forum C Programming
    Replies: 5
    Last Post: 11-28-2008, 04:50 AM
  3. printf output makes no sense. Is it a Pointer problem?
    By officedog in forum C Programming
    Replies: 3
    Last Post: 10-03-2008, 09:01 AM
  4. Problem referencing structure elements by pointer
    By trillianjedi in forum C Programming
    Replies: 19
    Last Post: 06-13-2008, 05:46 PM
  5. Pointer problem with FILE *f in function
    By mabuhay in forum C Programming
    Replies: 6
    Last Post: 02-14-2006, 04:15 PM