Memory Order in Classes

This is a discussion on Memory Order in Classes within the C++ Programming forums, part of the General Programming Boards category; I want to create a class with a long array of doubles, but various sections of the array can also ...

  1. #1
    Optics with a Twist skewray's Avatar
    Join Date
    Dec 2006
    Location
    Claremont, CA
    Posts
    31

    Memory Order in Classes

    I want to create a class with a long array of doubles, but various sections of the array can also be accessed by individual names. In other words
    Code:
    myclass.storage[20]
    myclass.part[10]
    both access the same location. What is the most elegant way to get this done? Unions and #defines are both clumsy at best, as is relying on the storage order in the class being identical to the declaration order. Right now I have "part" be a function returning a pointer to (storage + 10), which requires an ugly extra set of parentheses.

    The application is scientific programming. I have routines that have a list of input variables and a list of output variables. Some routines need to know what the individual variables represent in order to compute values, while other routines just want the entire list of values in order to computer derivatives and such. There must be some way to do this elegantly in C++.

    Thanks for any tips,

    Brian

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,500
    It seems to me like you have a solution looking for a way to be implemented.

    Using array overlays and pointers to the middle of arrays is pretty hackish even in C.
    Sure it solves one aspect of the problem very neatly, but it's making life hard for the rest of it.

    In C++, you should be focussing on the problem side and designing interfaces which express the problem in intuitive ways.

    Exactly how you implement that inside the class should be entirely invisible to the outside world. That's the whole point, you can then reimplement the class in different ways and all the users are blissfully unaware of what's going on.

    Maybe explore the rich goodie bag of stuff which is the STL
    http://www.sgi.com/tech/stl/Vector.html
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Optics with a Twist skewray's Avatar
    Join Date
    Dec 2006
    Location
    Claremont, CA
    Posts
    31
    I am looking for a solution. Sometimes problems required more than one way to access data. I fail to see how most of your comments are constructive. Feel free to clarify.

    Brian

  4. #4
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    It seems to me that a clever interface providing references to these individual data slots and iterators to these groups of related data would be great. If you are that frustrated with parentheses, you could even look into operator overloading and see if anything fits your fancy.

    ╔╗╔╦══╦╗╔╦══╦╗
    ║╚╝║╔╗║╚╝║╔╗║║
    ║╔╗║╠╣║╔╗║╠╣╠╣
    ╚╝╚╩╝╚╩╝╚╩╝╚╩╝

    codez http://code.google.com/p/zxcvbn/

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    2,027
    You should use accessors to get the data in the class, thus hideing the difference between accessing the whole array and just the second part.

    The C++ elegance comes from the encapsilation that accessors provide.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  6. #6
    Optics with a Twist skewray's Avatar
    Join Date
    Dec 2006
    Location
    Claremont, CA
    Posts
    31
    I will probably end up using:
    Code:
    class
        {
        double vars[0] ;
        double V1[4] ;
        double V2[4] ;
        etc...
        }
    so I can access all the variables as a single array with .vars[] and each individual one with .V1[]. It may be Evil Incarnate, but maybe no one will notice if I work enough goto's into the code. I will just have to have a runtime routine to doublecheck that all the variables ended up where expected.

    Brian

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    2,027
    Or you could just learn object oriented programming. . .
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  8. #8
    Optics with a Twist skewray's Avatar
    Join Date
    Dec 2006
    Location
    Claremont, CA
    Posts
    31
    If I were a Great Master such as yourself, I would needn't to ask a question here. Now that we have exchanged barbs, I have a book that purports to be an object oriented introduction to C++, and says the word "accessor" refers to a function that does not alter the data. In my application, most routines will need to alter the data. Please enlighten me with regards to how I could use accessor functions to get a syntax as elegant as the one I gave above? Right now I am using
    Code:
    friend double* Q( RAY* ray ) { return ray->vars + VARS_OFFSET_Q ; }
    which gives might ugly code in use.

    Brian

  9. #9
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Code:
    class has array of stuff
    
    const something & operator [] (index) const returns stuff[index]
    stomething & operator [] (index) returns stuff[index]
    
    const iterator derivativestuffbegin const returns &stuff[beginofdstuff]
    const iterator derivativestuffend const returns &stuff[endofdstuff]
    
    iterator derivativestuffbegin returns &stuff[beginofdstuff]
    iterator derivativestuffend returns &stuff[endofdstuff]
    
    const iterator integralstuffbegin const returns &stuff[beginistuff];
    const iterator integralstuffend const returns &stuff[endistuff];
    
    iterator integralstuffbegin returns &stuff[beginistuff];
    iterator integralstuffend returns &stuff[endistuff];
    http://www.parashift.com/c++-faq-lit...html#faq-18.12

    ╔╗╔╦══╦╗╔╦══╦╗
    ║╚╝║╔╗║╚╝║╔╗║║
    ║╔╗║╠╣║╔╗║╠╣╠╣
    ╚╝╚╩╝╚╩╝╚╩╝╚╩╝

    codez http://code.google.com/p/zxcvbn/

  10. #10
    Registered User
    Join Date
    Apr 2006
    Posts
    2,027
    I don't mean to sound snobby. I am actually not as much of an expert as I sometimes make myself out to be.

    But learning the principles of OO is probably a good idea because it is used alot in proffestional developement. I suggest you read and follow that book of yours because it really is the latest common practice.

    C++ OO can actually lead to some lenthy code compaired to procedural programming. That part is not a garenteed benifit. Indeed for small programs making elaborate classes is usually overkill. But for large programs OO helps keep the parts in seperate managable pieces, amung other things.

    Most of the time routines either read data or change data, but not both. Accessors are used to standardize reading data, and mutators are used to standardize changing the data. If you need more advanced operations, you should make them meathods. But you don't want meathods for things not directly related to the class.

    So instead of the above line of code you gave, I would suggest this:
    Code:
    class Data{
        private:
            cons int STORE_SIZE = 20;
            cons int VARS_OFFSET_Q = 10;
            int storage[STORE_SIZE];
        public:
            //Note: these meathods are made inline for a shorter example code.
            //It is probably better to make them not inline.
            const int *getStorage() {return storage}
            const int *getPart(){return storage + VARS_OFFSET_Q}
            void setStorage(int *store) : storage(store) {}
    };
    The use of this may seem strange at first. Instead of that extra set of parenthesis you were first talking about, you have 5 addinional characters. But the advantage is that it's the same for both part and storage. And should be the same for most other classes.
    Last edited by King Mir; 12-10-2006 at 08:55 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  11. #11
    Registered User
    Join Date
    Apr 2006
    Posts
    2,027
    Quote Originally Posted by Tonto
    Code:
    class has array of stuff
    
    const something & operator [] (index) const returns stuff[index]
    stomething & operator [] (index) returns stuff[index]
    
    const iterator derivativestuffbegin const returns &stuff[beginofdstuff]
    const iterator derivativestuffend const returns &stuff[endofdstuff]
    
    iterator derivativestuffbegin returns &stuff[beginofdstuff]
    iterator derivativestuffend returns &stuff[endofdstuff]
    
    const iterator integralstuffbegin const returns &stuff[beginistuff];
    const iterator integralstuffend const returns &stuff[endistuff];
    
    iterator integralstuffbegin returns &stuff[beginistuff];
    iterator integralstuffend returns &stuff[endistuff];
    http://www.parashift.com/c++-faq-lit...html#faq-18.12
    Yep, this would be even more elegant than what I wrote. But if the only difference between the integralstuff and the derivativestuff is that the dirivative stuff is a smaller list starting later on in the sequence, this might be overkill. Just returning the array or other container with the data should be enough.
    Last edited by King Mir; 12-10-2006 at 08:40 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  12. #12
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,500
    > friend double* Q( RAY* ray ) { return ray->vars + VARS_OFFSET_Q ; }
    So don't make it a function, make it a variable
    Code:
    class myclass {
      private:
        double data[20];
      public:
        myclass ( ) {
          Q = &data[10];
        }
      friend double *Q;
    };
    Then you can just use
    Q[5] as being an alias for data[15]
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  13. #13
    Optics with a Twist skewray's Avatar
    Join Date
    Dec 2006
    Location
    Claremont, CA
    Posts
    31
    This code snippet doesn't compile:

    g++ x.C
    x.C:9: error: ‘Q’ is neither function nor member function; cannot be declared friend
    x.C: In constructor ‘myclass::myclass()’:
    x.C:7: error: ‘Q’ was not declared in this scope

    On the other hand, it is exactly what I was looking for in the first place. Other posts have made me think that what I wanted may not be optimal.

    Brian

  14. #14
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,500
    Make Q a public member of the class then?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems with shared memory shmdt() shmctl()
    By Jcarroll in forum C Programming
    Replies: 1
    Last Post: 03-17-2009, 10:48 PM
  2. Memory usage and memory leaks
    By vsanandan in forum C Programming
    Replies: 1
    Last Post: 05-03-2008, 05:45 AM
  3. Classes, Subclasses & Dynamic Memory
    By CaeZaR in forum C++ Programming
    Replies: 6
    Last Post: 02-06-2006, 05:07 PM
  4. Managing shared memory lookups
    By clancyPC in forum Linux Programming
    Replies: 0
    Last Post: 10-08-2003, 04:44 AM
  5. Trivial: Get/Set + Function Order in Classes
    By Ashes999 in forum C++ Programming
    Replies: 10
    Last Post: 07-08-2003, 11:09 AM

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