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,10 +9,26 @@
|
||||||
class StringPtr: public std::vector<std::string *>
|
class StringPtr: public std::vector<std::string *>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class iterator: public
|
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>
|
std::iterator<std::random_access_iterator_tag, std::string>
|
||||||
{
|
{
|
||||||
friend class StringPtr;
|
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;
|
std::vector<std::string *>::iterator d_current;
|
||||||
|
|
||||||
iterator(std::vector<std::string *>::iterator const ¤t);
|
iterator(std::vector<std::string *>::iterator const ¤t);
|
||||||
|
@ -22,26 +38,14 @@ class StringPtr: public std::vector<std::string *>
|
||||||
iterator operator--(int);
|
iterator operator--(int);
|
||||||
iterator &operator++();
|
iterator &operator++();
|
||||||
iterator operator++(int);
|
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); // increment over `n' steps
|
||||||
iterator &operator-=(int step); // decrement over `n' steps
|
iterator &operator-=(int step); // decrement over `n' steps
|
||||||
|
|
||||||
|
std::string &operator*() const;
|
||||||
std::string *operator->() const;// access the fields of the
|
std::string *operator->() const;// access the fields of the
|
||||||
// struct an iterator points
|
// struct an iterator points
|
||||||
// to. E.g., it->length()
|
// to. E.g., it->length()
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
|
||||||
|
|
||||||
iterator begin();
|
|
||||||
iterator end();
|
|
||||||
reverse_iterator rbegin();
|
|
||||||
reverse_iterator rend();
|
|
||||||
};
|
};
|
||||||
//=
|
//=
|
||||||
|
|
||||||
|
@ -80,21 +84,24 @@ inline StringPtr::iterator StringPtr::iterator::operator++(int)
|
||||||
}
|
}
|
||||||
//=
|
//=
|
||||||
//OPEQ
|
//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
|
//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
|
//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*
|
//OP*
|
||||||
|
@ -104,21 +111,26 @@ inline std::string &StringPtr::iterator::operator*() const
|
||||||
}
|
}
|
||||||
//=
|
//=
|
||||||
//CMP
|
//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
|
//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-
|
//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
|
//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
|
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.
|
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
|
No friend declaration is required to grant a nested class access to the
|
||||||
the private members of its surrounding class. After all, a nested class is a
|
private members of its surrounding class. Static members of the surrounding
|
||||||
type defined by its surrounding class and as such objects of the nested class
|
class can directly be accessed, other members can be accessed if a surrounding
|
||||||
are members of the outer class and thus can access all the outer class's
|
class object is defined by or passed to members of the nested class. After
|
||||||
members. Here is an example showing this principle. The example won't compile
|
all, a nested class is a type defined by its surrounding class and as such
|
||||||
as members of the class tt(Extern) are denied access to tt(Outer)'s private
|
objects of the nested class are members of the outer class and thus can access
|
||||||
members, but tt(Outer::Inner)'s members em(can) access tt(Outer)'s private
|
all the outer class's members. Here is an example showing this principle. The
|
||||||
members:
|
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(
|
verb(
|
||||||
class Outer
|
class Outer
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,42 @@ class definition:
|
||||||
return d_variable;
|
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(
|
itemization(
|
||||||
it() The class tt(FirstWithin) is visible outside and inside
|
it() The class tt(FirstWithin) is visible outside and inside
|
||||||
tt(Surround). The class tt(FirstWithin) thus has global visibility.
|
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
|
it() As always, an object of the class type is required before
|
||||||
its members can be called. This also holds true for nested classes.
|
its members can be called. This also holds true for nested classes.
|
||||||
)
|
)
|
||||||
To grant the surrounding class access rights to the private members
|
To grant the surrounding class access rights to the private members of a
|
||||||
of its nested classes or to grant nested classes access rights to the
|
nested class the nested class may declare its surrounding class as a
|
||||||
private members of the surrounding class, the classes can be defined as
|
friend. Conversely, as nested classes can be considered members of their
|
||||||
tt(friend) classes (see section ref(NESTEDFRIENDS)).
|
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
|
Although nested classes can be considered members of the surrounding
|
||||||
members of nested classes are em(not) members of the surrounding class. So, a
|
class, members of nested classes are em(not) members of the surrounding
|
||||||
member of the class tt(Surround) may not access tt(FirstWithin::var)
|
class: members of the class tt(Surround) may not directly call
|
||||||
directly. This is understandable considering that a tt(Surround) object is not
|
tt(FirstWithin::var). This is understandable considering that a
|
||||||
also a tt(FirstWithin) or tt(SecondWithin) object. In fact, nested classes are
|
tt(Surround) object is not also a tt(FirstWithin) or tt(SecondWithin)
|
||||||
just typenames. It is not implied that objects of such classes automatically
|
object. In fact, nested classes are just typenames. It is not implied that
|
||||||
exist in the surrounding class. If a member of the surrounding class should
|
objects of such classes automatically exist in the surrounding class. If a
|
||||||
use a (non-static) member of a nested class then the surrounding class must
|
member of the surrounding class should use a (non-static) member of a nested
|
||||||
define a nested class object, which can thereupon be used by the members of
|
class then the surrounding class must define a nested class object, which can
|
||||||
the surrounding class to use members of the nested class.
|
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
|
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
|
class tt(Outer) and a nested class tt(Inner). The class tt(Outer) contains a
|
||||||
|
|
Loading…
Reference in a new issue