问题描述:

Suppose I have a class which contains some other class which in turn contains some container. And I need to be able to iterate over that container in the outermost class without exposing it publicly. It can be done by the means of private inheritance or by exposing container iterators.

Exposing iteratos:

template <typename Container>

class Details

{

public:

//some methods useful for the Test class

using ContIter = typename Container::const_iterator;

ContIter begin() { return std::begin(cont); }

ContIter end() { return std::end(cont); }

private:

Container cont;

};

template <typename Container>

class Test

{

public:

void contrived() {

for(const auto& i : details)

;//do something

}

private:

Details<Container> details;

};

Private inheritance:

template <typename Container>

class Details

{

public:

//some methods useful for the Test class

protected:

Container cont;

};

template <typename Container>

class Test : Details<Container>

{

public:

void contrived() {

for(const auto& i : this->cont)

;//do something

}

};

I am interested what should be the preferred way of doing that kind of stuff, pros and cons of both approaches and other possible solutions. It is mostly hypothetical question as I have changed my code design, but nonetheless I am still curious.

网友答案:

The main difference between the two approaches is that the first implementation publicly exposes a range suitable for iterating over the elements of your container, while the second implementation exposes the whole container, but only to its derived classes.

The preferred approach depends on your design: if you wish to expose a range over which you can iterate to the outside of your class, use the first approach; if you would rather not expose a range for iteration, consider making begin() and end() protected, rather than public.

I would recommend agains the approach with private inheritance, because it sends a wrong message to the readers of your code. Generally, non-public inheritance says that the derived class is implemented in terms of its base class. However, your code uses this technique for access control, which may puzzle the reader of your code.

相关阅读:
Top