Problems with functions in a class with pointer to self

This is a discussion on Problems with functions in a class with pointer to self within the C++ Programming forums, part of the General Programming Boards category; Hi guys, I've got a class that has a member variable which is a pointer to an object of the ...

  1. #1
    Registered User
    Join Date
    Apr 2002
    Posts
    80

    Problems with functions in a class with pointer to self

    Hi guys,

    I've got a class that has a member variable which is a pointer to an object of the same class. I'm having problems dealing with some of the constructors (mainly copy) and assignment operator. I don't think I've ever written classes with this special case, although I realize it shouldn't be too hard. If you have any ideas on how to best rewrite my copy construct, assignment operator, or anything else (trivial constructors??), please let me know!

    Thanks, Andrew

    Code:
    Location.h
    
    #ifndef LOCATION_H
    #define LOCATION_H
    
    using namespace std;
    
    class Location
    {
    private:
        int row, col, cost;
        Location* history;
    
    public:
        Location()
        { row = col = cost = 0; history = NULL; }
        Location(int r, int c)
        { row = r; col = c; cost = 0; history = NULL; }
        Location(const Location& loc);
        ~Location()
        { delete history; history = NULL; }
        int getRow() const
        { return row; }
        int getCol() const
        { return col; }
        int getCost() const
        { return cost; }
        void setCost(int c)
        { cost = c; }
        void setHistory(Location loc)
        { *history = loc; }
        Location& getHistory() const
        { return *history; }
        bool operator < (const Location& loc) const
        { return (cost > loc.getCost()); }
        Location& operator =(const Location& loc);   
    };
    
    #endif
    
    
    
    Location.cpp
    
    #include"location.h"
    
    using namespace std;
    
    Location::Location(const Location& loc)
    {
        if (loc.history != NULL)
        {
            row = loc.row; col = loc.col; cost = loc.cost;
        }
        history = new Location();
        *history = loc.getHistory();
    }
    
    Location& Location::operator =(const Location& loc)
    {
        if (this != &loc)
        { 
            row = loc.row; col = loc.col; cost = loc.cost;
            if (history != NULL) delete history;
            history = new Location(loc.getHistory()); 
        }
      
        return *this;
    }

  2. #2
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    You aren't dereferencing your pointers correctly. More correctly, I should say you are dereferencing something that you shouldn't.

    Code:
    *history = loc.getHistory();
    Is incorrect. The best way to do this would be

    Code:
    history = loc.history;
    Even though history is private you can do this since they are both the same class. You could also take the address of getHistory()'s return and set history equal to that, but my example is much cleaner.

  3. #3
    Registered User
    Join Date
    Apr 2002
    Posts
    80
    I understand what you're doing. I think initially I was thinking that we can't do history = loc.history, because that would just be assigning the pointer, rather than the history element, but, I'm pretty sure I want to assign them to point at the same object.

    I'll see how that works,
    Thanks

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,707
    It appears that you are creating an endless loop, too. Look:

    Code:
    Location& Location :: operator =(const Location& loc)
    {
     //...
            history = new Location(loc.getHistory()); 
     //...
    }
    This will in turn operator = ad infinitum via the new Location(Location&) call!

    One solution is to simply duplicate operator = 's code in the constructor in order to prevent the infinite recursion:

    (Also rewrote getHistory() to prevent raising an exception if history == NULL)

    Code:
    Location& getHistory() const
    {
      if(history == 0) history = new Location(); 
      return *history; 
    }
    
    
    Location::Location(const Location& loc)
    {
        
      if (loc.history != NULL)
        {
            getHistory().row = loc.getHistory().row; 
            getHistory().col   = loc.getHistory().col; 
            getHistory().cost = loc.getHistory().cost;
        }
        
           row = loc.row; 
           col = loc.col; 
           cost = loc.cost;
     }
    Last edited by Sebastiani; 02-01-2003 at 03:38 PM.
    Code:
    #include <cmath>
    #include <complex>
    bool flip(bool value)
    {
           return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0)*(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Registered User
    Join Date
    Apr 2002
    Posts
    80
    Sorry for the absence,

    I had elected to go another route, but am decided again to go with this method, of a pointer to a Location.

    My question regarding the presented code is this:

    Will the assignment operator and copy constructor adequetly copy the history. In other words: I'm going to need to get at the history of the history of the history, etc. So, I can't just copy the element, I need to get history to point at the actualy history element.

    Perhaps that makes more sense?

    Thanks!

  6. #6
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    May I suggest creating a location object that knows nothing of it's history and another object that maintains a list/vector of locations. Have the constructor create a location and push_back that location to your history, then have all your methods that would not have created a new location route thier calls to history.back().member_fn(); The methods that would have added a new state to your history push this new state to the back.

    If your history is constant grab boost and use a shared_ptr, this will allow shallow copies (new locations little more expensive than copying a pointer) but destruction is handled cleanly (there can be no cycles)

  7. #7
    Registered User
    Join Date
    Apr 2002
    Posts
    80
    Thanks, I'll give some of that a go.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  2. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 09:33 AM
  4. base class pointer problems
    By ... in forum C++ Programming
    Replies: 3
    Last Post: 11-16-2003, 10:27 PM
  5. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21