简体   繁体   中英

C++ Passing a member variable to a member class

I have legacy code where a similar method is used to cycle through a sequential container (vector in this example. Some implementations use other kinds of containers). So I factored it out into a template so I could reuse the same piece of code for any container type.

template<template<class, class> class TContainer, class TObject>
class cycle
{
public:

    explicit cycle( TContainer<TObject, std::allocator<TObject>> & container )
        : mContainer( container ), index(0) {}

    TObject getNext(int numObjectsToCycle) 
    { return mContainer[index++ % numObjectsToCycle]; }
private:
    TContainer<TObject, std::allocator<TObject>> & mContainer;
    int index;
};

Then my class has a cycler to cycle through my variable numbers.

class myClass
{
   std::vector<int> numbers;

public:
   cycle<vector, int> cycler;
   // Is it safe to pass numbers since it is declared first??
   myClass() : cycler(numbers) {} 

};

Then, I use the code like below.:

myObject.cycler.getNext(size);

Is it a good programming practice to pass the vector "numbers" to cycler? Is there a better way of implementing my template?

The code really is to be able to infinitely loop through objects. My class is invoked from external code that just calls a member method, and I want to be able to just call getNext() so I wouldn't have to use an index.

In the standard library another "pattern" exists and it's the iterator pattern . Basically every container type implements begin and end which returns, respectively, the iterator to the first element and the past-the-end element (which is always guaranteed to exists).

This works for every container type, from std::vector to std::array including C-style arrays with std::begin and std::end . If you want to loop in a generic container you can do, for example:

template<typename Container>
void cicle(Container const& c) {
    for (auto const& i : c) {
        // …
    }
}

or, to better visualize the pattern:

template<typename Container>
void cicle(Container const& c) {
    for (auto it = std::begin(c); it != std::end(c); ++it) {
        // …
    }
}

Live demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM