Thread: Iterating through a template class's private, dynamic array from main

  1. #1
    Registered User
    Join Date
    Feb 2014
    Posts
    5

    Iterating through a template class's private, dynamic array from main

    I have a template class which contains a private, dynamic array of its template type. What I'm trying to do is, from main, iterate through each of its array's elements and modify each of them.

    So far I have accomplished this by making a pointer of the type the template class ends up using, and passing a reference to this pointer to a function in the template class which moves it to the next element. Then I just dereference the pointer in main and modify it. This is in a while loop that continues until all elements in the array have been covered.

    But this seems like bad technique and I was wondering what a better way would be? It seems like I would at least need some kind of accessor function(s) in the template class, but it doesn't seem very encapsulationy to just have a getter that accepts an array index and return a reference to it.

    Specifically, this is what I'm doing now:

    In main I create a pointer of the type I'm using for the template class:
    CustomerType *customerPointer = new CustomerType();

    I then pass this to a function in the template class by reference (this is called in main):
    Line.updateWaitTimes(customerPointer); (Line is the template object)

    In the template class, I then modify the address the pointer holds:
    customerPointer = &theArray[someIndex];

    Back in main, I modify the object the pointer now points to:
    (*customerPointer).incrementWaitTimes();

    After this has looped through each customerType object in the array I delete customerPointer;

    This is working, but seems poorly done, any help is appreciated.

    EDIT: Also I can't call incrementWaitTime() inside the template class on each item in the array as the template class knows nothing about customerType objects (just accepts that as its template type)
    Last edited by Instinct212; 02-20-2014 at 04:50 PM.

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    Let us pretend you have a method `void Class::set(int fIndex, const ElementType & fNode);'; what does `set' do to protect the internal array?

    In other words, does the template class do anything other than store values the client gives?

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  3. #3
    Registered User
    Join Date
    Feb 2014
    Posts
    5
    I guess it doesn't protect the internal array, but my version of set is:
    Code:
    template<class Type>
    void QueueType<Type>::addElement(Type newElement) {
        if (isEmpty()) {
            queueArray[0] = newElement;
            front = back = 0;
            numElements = 1;
        } else {
            back = (back + 1) % SIZE;
            queueArray[back] = newElement;
            numElements++;
        }
    }
    (I'm implementing it as a circular array) It doesn't really do much aside from store values, reposition itsself (due to being circular) after item removal, and return the number of elements it has. My updateWaitTimes function in the template is:
    Code:
    template<class Type>
    void QueueType<Type>::updateWaitTimes(Type*& element, int& position, int& counter) {
        if (isEmpty()) {
            element = NULL;
        } else {
            if (position == 0) {
                position = front;
            }
            element = &queueArray[position];
            position = (position + 1) % SIZE;
        }
        if (counter == numElements) {
            element = NULL;
        }
        counter++;
    }
    (Type ends up being customerType and element is customerPointer) Where it actually takes 2 other int references to know when to stop and set the pointer to NULL, but all it really does is sets the pointer to the next element in its array.

    Do you think it would be better to just add an iterator class along with begin/end/proper overloading functions needed so I can just use a range-based for loop in main? Instead of my weird pointer shenanigans.

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    I guess it doesn't protect the internal array
    O_o

    If any value is allowed, you have a "false sense of security" with respect to encapsulation. The template class is "encapsulated" by protecting the relationship between `front', `back', `SIZE', and similar objects that govern the behavior of the instances of the class. If you've done that job, you don't need to worry about protecting the values container within the array. You aren't violating "encapsulation" by providing unrestricted access to each value because the class exists to provide that access.

    To be clear, some classes do limit the domain/range of values; with such classes, ensuring the instance only contains valid values is part of "encapsulation". For example, consider a collection of UNICODE--a form of encoding--characters as a string: UNICODE places limits on the valid values of any given "codepoint" so the class should then protect the values stored.

    The difference here is really whether a class "owns" the values or just the storage containing those values.

    Do you think it would be better to just add an iterator class along with begin/end/proper overloading functions needed so I can just use a range-based for loop in main?
    Yes. I do. However, I don't recommend that because of "encapsulation". Anyone familiar with the iterator "protocol" of the standard containers will necessarily already be familiar with your class interface if you follow the same "protocol".

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  5. #5
    Registered User
    Join Date
    Feb 2014
    Posts
    5
    Oh ok, I do protect the relationships between front/back/SIZE, etc. in my queueType::reposition() method so I assume the array is protected then. That makes sense, my idea was for this class to just own the storage containing those values so I guess encapsulation isn't violated there.

    How would the fact that people who are familiar with the workings of iterators would also be familiar with my queueType's interface break encapsulation? Are there any other methods for this type of iteration you would recommend (allowing me to loop through the array in main and make a modification to each element)? I also just realized that this type of iterator might not be easily implemented for use with a circular array class anyway, in overloading the prefix increment operator the iterator class would have to be able to see queueType's SIZE to know when to loop back around to the first element in the array (if for example, SIZE = 25, front = 23, back = 7).

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    How would the fact that people who are familiar with the workings of iterators would also be familiar with my queueType's interface break encapsulation?
    O_o

    I don't understand how you've asked the question.

    I also just realized that this type of iterator might not be easily implemented for use with a circular array class anyway, in overloading the prefix increment operator the iterator class would have to be able to see queueType's SIZE to know when to loop back around to the first element in the array (if for example, SIZE = 25, front = 23, back = 7).
    Trivial.

    You only need to separate navigation from storage; the iterators own the context for navigation; the class owns two iterators representing `front' and `back'.

    Try your hand; if you need further help ask.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. GCC:Static(fixed-length) array in template class
    By tra86 in forum C++ Programming
    Replies: 9
    Last Post: 06-21-2011, 03:00 PM
  2. Replies: 2
    Last Post: 08-18-2010, 03:24 PM
  3. Iterating over private vector
    By mrpringle in forum C++ Programming
    Replies: 9
    Last Post: 08-15-2010, 11:56 AM
  4. Replies: 3
    Last Post: 04-10-2009, 02:20 AM
  5. Template Array Class
    By hpy_gilmore8 in forum C++ Programming
    Replies: 15
    Last Post: 04-11-2004, 11:15 PM

Tags for this Thread