mirror of
https://gitlab.com/fbb-git/cppannotations
synced 2024-11-16 07:48:44 +01:00
nested classes: not in-class, building iterators updated accordingly
This commit is contained in:
parent
b2e5f30ed4
commit
c1a175cff5
3 changed files with 115 additions and 63 deletions
|
@ -9,40 +9,44 @@
|
|||
class StringPtr: public std::vector<std::string *>
|
||||
{
|
||||
public:
|
||||
class iterator: public
|
||||
std::iterator<std::random_access_iterator_tag, std::string>
|
||||
{
|
||||
friend class StringPtr;
|
||||
std::vector<std::string *>::iterator d_current;
|
||||
|
||||
iterator(std::vector<std::string *>::iterator const ¤t);
|
||||
|
||||
public:
|
||||
iterator &operator--();
|
||||
iterator operator--(int);
|
||||
iterator &operator++();
|
||||
iterator operator++(int);
|
||||
bool operator==(iterator const &other) const;
|
||||
bool operator!=(iterator const &other) const;
|
||||
int operator-(iterator const &rhs) const;
|
||||
std::string &operator*() const;
|
||||
bool operator<(iterator const &other) const;
|
||||
iterator operator+(int step) const;
|
||||
iterator operator-(int step) const;
|
||||
iterator &operator+=(int step); // increment over `n' steps
|
||||
iterator &operator-=(int step); // decrement over `n' steps
|
||||
std::string *operator->() const;// access the fields of the
|
||||
// struct an iterator points
|
||||
// to. E.g., it->length()
|
||||
};
|
||||
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
class iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
reverse_iterator rbegin();
|
||||
reverse_iterator rend();
|
||||
};
|
||||
|
||||
class StringPtr::iterator: public
|
||||
std::iterator<std::random_access_iterator_tag, std::string>
|
||||
{
|
||||
friend class StringPtr;
|
||||
|
||||
friend bool operator==(iterator const &lhs, iterator const &rhs);
|
||||
friend int operator-(iterator const &lhs, iterator const &rhs);
|
||||
friend bool operator<(iterator const &lhs, iterator const &rhs);
|
||||
friend iterator operator+(iterator const &lhs, int step);
|
||||
friend iterator operator-(iterator const &lhs, int step);
|
||||
|
||||
std::vector<std::string *>::iterator d_current;
|
||||
|
||||
iterator(std::vector<std::string *>::iterator const ¤t);
|
||||
|
||||
public:
|
||||
iterator &operator--();
|
||||
iterator operator--(int);
|
||||
iterator &operator++();
|
||||
iterator operator++(int);
|
||||
|
||||
iterator &operator+=(int step); // increment over `n' steps
|
||||
iterator &operator-=(int step); // decrement over `n' steps
|
||||
|
||||
std::string &operator*() const;
|
||||
std::string *operator->() const;// access the fields of the
|
||||
// struct an iterator points
|
||||
// to. E.g., it->length()
|
||||
};
|
||||
//=
|
||||
|
||||
//PRIVATEIMP
|
||||
|
@ -80,21 +84,24 @@ inline StringPtr::iterator StringPtr::iterator::operator++(int)
|
|||
}
|
||||
//=
|
||||
//OPEQ
|
||||
inline bool StringPtr::iterator::operator==(iterator const &other) const
|
||||
inline bool operator==(StringPtr::iterator const &lhs,
|
||||
StringPtr::iterator const &rhs)
|
||||
{
|
||||
return d_current == other.d_current;
|
||||
return lhs.d_current == rhs.d_current;
|
||||
}
|
||||
//=
|
||||
//OPNEQ
|
||||
inline bool StringPtr::iterator::operator!=(iterator const &other) const
|
||||
inline bool operator!=(StringPtr::iterator const &lhs,
|
||||
StringPtr::iterator const &rhs)
|
||||
{
|
||||
return d_current != other.d_current;
|
||||
return not (lhs == rhs);
|
||||
}
|
||||
//=
|
||||
//OPSUB
|
||||
inline int StringPtr::iterator::operator-(iterator const &rhs) const
|
||||
inline int operator-(StringPtr::iterator const &lhs,
|
||||
StringPtr::iterator const &rhs)
|
||||
{
|
||||
return d_current - rhs.d_current;
|
||||
return lhs.d_current - rhs.d_current;
|
||||
}
|
||||
//=
|
||||
//OP*
|
||||
|
@ -104,21 +111,26 @@ inline std::string &StringPtr::iterator::operator*() const
|
|||
}
|
||||
//=
|
||||
//CMP
|
||||
inline bool StringPtr::iterator::operator<(iterator const &other) const
|
||||
inline bool operator<(StringPtr::iterator const &lhs,
|
||||
StringPtr::iterator const &rhs)
|
||||
{
|
||||
return d_current < other.d_current;
|
||||
return lhs.d_current < rhs.d_current;
|
||||
}
|
||||
//=
|
||||
//OPADD
|
||||
inline StringPtr::iterator StringPtr::iterator::operator+(int step) const
|
||||
inline StringPtr::iterator operator+(StringPtr::iterator const &lhs, int step)
|
||||
{
|
||||
return iterator(d_current + step);
|
||||
StringPtr::iterator ret{ lhs };
|
||||
ret.d_current += step; // avoids ambiguity
|
||||
return ret;
|
||||
}
|
||||
//=
|
||||
//OP-
|
||||
inline StringPtr::iterator StringPtr::iterator::operator-(int step) const
|
||||
inline StringPtr::iterator operator-(StringPtr::iterator const &lhs, int step)
|
||||
{
|
||||
return iterator(d_current - step);
|
||||
StringPtr::iterator ret{ lhs };
|
||||
ret.d_current -= step; // avoids ambiguity
|
||||
return ret;
|
||||
}
|
||||
//=
|
||||
//OPARITH
|
||||
|
|
|
@ -2,14 +2,16 @@ To grant nested classes access rights to the private members of other nested
|
|||
classes, or to grant a surrounding class access to the private members of its
|
||||
nested classes the hi(friend: nested classes)tt(friend) keyword must be used.
|
||||
|
||||
Note that no friend declaration is required to grant a nested class access to
|
||||
the private members of its surrounding class. After all, a nested class is a
|
||||
type defined by its surrounding class and as such objects of the nested class
|
||||
are members of the outer class and thus can access all the outer class's
|
||||
members. Here is an example showing this principle. The example won't compile
|
||||
as members of the class tt(Extern) are denied access to tt(Outer)'s private
|
||||
members, but tt(Outer::Inner)'s members em(can) access tt(Outer)'s private
|
||||
members:
|
||||
No friend declaration is required to grant a nested class access to the
|
||||
private members of its surrounding class. Static members of the surrounding
|
||||
class can directly be accessed, other members can be accessed if a surrounding
|
||||
class object is defined by or passed to members of the nested class. After
|
||||
all, a nested class is a type defined by its surrounding class and as such
|
||||
objects of the nested class are members of the outer class and thus can access
|
||||
all the outer class's members. Here is an example showing this principle. The
|
||||
example won't compile as members of the class tt(Extern) are denied access to
|
||||
tt(Outer)'s private members, but tt(Outer::Inner)'s members em(can) access
|
||||
tt(Outer)'s private members:
|
||||
verb(
|
||||
class Outer
|
||||
{
|
||||
|
|
|
@ -52,7 +52,42 @@ class definition:
|
|||
return d_variable;
|
||||
}
|
||||
)
|
||||
Here access to the members is defined as follows:
|
||||
|
||||
First note that in the Annotations(), in order to save space, nested class
|
||||
interfaces are usually declared inside their surrounding class, as shown
|
||||
above. For real-life projects this practice is questionable, as it clobbers
|
||||
class interfaces, similarly to providing classes with in-class member
|
||||
implementations. Instead of nesting class interfaces put them next to each
|
||||
other:
|
||||
verb(
|
||||
class Surround
|
||||
{
|
||||
class SecondWithin;
|
||||
|
||||
public:
|
||||
class FirstWithin;
|
||||
};
|
||||
|
||||
class FirstWithin
|
||||
{
|
||||
int d_variable;
|
||||
|
||||
public:
|
||||
FirstWithin();
|
||||
int var() const;
|
||||
};
|
||||
|
||||
class SecondWithin
|
||||
{
|
||||
int d_variable;
|
||||
|
||||
public:
|
||||
SecondWithin();
|
||||
int var() const;
|
||||
};
|
||||
)
|
||||
|
||||
For these three classes access to members is defined as follows:
|
||||
itemization(
|
||||
it() The class tt(FirstWithin) is visible outside and inside
|
||||
tt(Surround). The class tt(FirstWithin) thus has global visibility.
|
||||
|
@ -75,21 +110,24 @@ tt(SecondWithin) directly.
|
|||
it() As always, an object of the class type is required before
|
||||
its members can be called. This also holds true for nested classes.
|
||||
)
|
||||
To grant the surrounding class access rights to the private members
|
||||
of its nested classes or to grant nested classes access rights to the
|
||||
private members of the surrounding class, the classes can be defined as
|
||||
tt(friend) classes (see section ref(NESTEDFRIENDS)).
|
||||
To grant the surrounding class access rights to the private members of a
|
||||
nested class the nested class may declare its surrounding class as a
|
||||
friend. Conversely, as nested classes can be considered members of their
|
||||
surrounding class their member functions have full access to the outer class
|
||||
members, if they are provided with an outer class object (see section
|
||||
ref(NESTEDFRIENDS)).
|
||||
|
||||
Nested classes can be considered members of the surrounding class, but
|
||||
members of nested classes are em(not) members of the surrounding class. So, a
|
||||
member of the class tt(Surround) may not access tt(FirstWithin::var)
|
||||
directly. This is understandable considering that a tt(Surround) object is not
|
||||
also a tt(FirstWithin) or tt(SecondWithin) object. In fact, nested classes are
|
||||
just typenames. It is not implied that objects of such classes automatically
|
||||
exist in the surrounding class. If a member of the surrounding class should
|
||||
use a (non-static) member of a nested class then the surrounding class must
|
||||
define a nested class object, which can thereupon be used by the members of
|
||||
the surrounding class to use members of the nested class.
|
||||
Although nested classes can be considered members of the surrounding
|
||||
class, members of nested classes are em(not) members of the surrounding
|
||||
class: members of the class tt(Surround) may not directly call
|
||||
tt(FirstWithin::var). This is understandable considering that a
|
||||
tt(Surround) object is not also a tt(FirstWithin) or tt(SecondWithin)
|
||||
object. In fact, nested classes are just typenames. It is not implied that
|
||||
objects of such classes automatically exist in the surrounding class. If a
|
||||
member of the surrounding class should use a (non-static) member of a nested
|
||||
class then the surrounding class must define a nested class object, which can
|
||||
thereupon be used by the members of the surrounding class to use members of
|
||||
the nested class.
|
||||
|
||||
For example, in the following class definition there is a surrounding
|
||||
class tt(Outer) and a nested class tt(Inner). The class tt(Outer) contains a
|
||||
|
|
Loading…
Reference in a new issue