Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C++ Array

  1. Apr 20, 2010 #1
    I have been pulling my hair out on this one.

    I have a double** that is a private member of a class. The constructor declares and initializes it as a 2 dimensional dynamic array of doubles (an array of arrays). Then it sets every element of the array equal to 0 with a set of two nested for loops.

    This seems to work fine.

    However, whenever any of my accessor or mutator functions that are also members of the class try to use this array using the array[][] subscripts, I get an error. This seems to be because somehow the address of the pointer array gets "lost" after the constructor runs.

    I have no idea why it would happen. Private pointer variables that are a member of a class should retain their values for all functions used by that instance of the class.
     
  2. jcsd
  3. Apr 20, 2010 #2
    They should.

    Post some code.
     
  4. Apr 20, 2010 #3

    Mark44

    Staff: Mentor

    Can you show us your code? What you're saying seems to be contradictory - that you have a private member that is a double ** pointer, and that a constructor declares it and initializes it.

    If the constructor declares it, it seems to me that your pointer is a local variable in the constructor, so its scope is only in the constructor. It wouldn't be visible outside the constructor.
     
  5. Apr 20, 2010 #4
    Good point.
     
  6. Apr 20, 2010 #5
    Yes, that was my problem. I figured it out not one minute before I read your reply, but thank you. I am fairly new to object oriented programming.

    I wasted a good three hours last night on this. I should have just asked, it would have saved a lot of time.

    The more time you waste on stupid mistakes, the less likely you are to make them in the future. :)
     
  7. Apr 20, 2010 #6
    Also, hopefully you have a copy and an =operator constructor overload, and put a delete[] loop in the destructor.

    Then you might overload the member function for [][]
     
  8. Apr 20, 2010 #7
    Of course! Many big arrays could cause a serious memory leak. :)
     
  9. Apr 20, 2010 #8
    Really? The book says it is difficult or impossible to do, depending on the circumstances.
     
  10. Apr 20, 2010 #9

    Mark44

    Staff: Mentor

    This really is less about OO programming and more about the scope of variables. If you have a local nonstatic variable in a function, it springs to life when the function is entered and dies when the function is exited.
    That's a good point and one that is more valuable that a lot of people realize. Part of learning is about dead ends and wrong turns.
     
  11. Apr 20, 2010 #10
    For some reason, I was not understanding that the compiler treated variables declared in the header file as variable declarations. I was thinking that they were treated more as prototypes and were actually declared by the constructor (because, this is the first time I have actually created a constructor instead of using the default constructor). But now I understand that the scope of variables declared in the constructor is limited to the scope of the constructor function itself, a valuable, if time consuming lesson.
     
  12. May 1, 2010 #11
    Or better yet, just use a vector of vectors.

    It's not possible to do it directly, because there isn't actually an operator[][]. You have to define operator[] of your class to return a dummy object, then have operator[] of the dummy class return the actual value. Basic example would be something like

    Code (Text):
    using namespace std;

    // Container must supply operator[] and a "reference" typedef
    template<typename Container>
    class ArrayOperator
    {
      Container& m_container;

    public:
      ArrayOperator(Container& c) : m_container(c) {}

      typename Container::reference operator[](size_t n) { return m_container[n]; }
    };

    class Foo
    {
      vector<vector<int> > m_data;

    public:
      Foo(int x, int y) : m_data(x, vector<int>(y)) {}

      ArrayOperator<vector<int> > operator[](size_t n)
      {
        return ArrayOperator<vector<int> >(m_data[n]);
      }
    };

    int main()
    {
      Foo f(2, 3);

      f[0][1] = 5;

      return 0;
    }
    It really isn't worth the trouble most of the time IMO, plus all of the standard warnings about violating encapsulation, etc.
     
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook