📄 contain.h
字号:
*/
class PContainer : public PObject
{
PCLASSINFO(PContainer, PObject);
public:
/**@name Construction */
//@{
/**Create a new unique container.
*/
PContainer(
PINDEX initialSize = 0 ///< Initial number of things in the container.
);
/**Create a new refernce to container.
Create a new container referencing the same contents as the container
specified in the parameter.
*/
PContainer(
const PContainer & cont ///< Container to create a new reference from.
);
/**Assign one container reference to another.
Set the current container to reference the same thing as the container
specified in the parameter.
Note that the old contents of the container is dereferenced and if
it was unique, destroyed using the DestroyContents() function.
*/
PContainer & operator=(
const PContainer & cont ///< Container to create a new reference from.
);
/**Destroy the container class.
This will decrement the reference count on the contents and if unique,
will destroy it using the #DestroyContents()# function.
*/
virtual ~PContainer()
{ Destruct(); }
//@}
/**@name Common functions for containers */
//@{
/**Get the current size of the container.
This represents the number of things the container contains. For some
types of containers this will always return 1.
@return number of objects in container.
*/
virtual PINDEX GetSize() const;
/**Set the new current size of the container.
The exact behavious of this is determined by the descendent class. For
instance an array class would reallocate memory to make space for the
new number of elements.
Note for some types of containers this does not do anything as they
inherently only contain one item. The function returns TRUE always and
the new value is ignored.
@return
TRUE if the size was successfully changed. The value FALSE usually
indicates failure due to insufficient memory.
*/
virtual BOOL SetSize(
PINDEX newSize ///< New size for the container.
) = 0;
/**Set the minimum size of container.
This function will set the size of the object to be at least the size
specified. The #SetSize()# function is always called, either with the
new value or the previous size, whichever is the larger.
*/
BOOL SetMinSize(
PINDEX minSize ///< Possible, new size for the container.
);
/**Determine if the container is empty.
Determine if the container that this object references contains any
elements.
@return TRUE if #GetSize()# returns zero.
*/
virtual BOOL IsEmpty() const;
/**Determine if container is unique reference.
Determine if this instance is the one and only reference to the
container contents.
@return TRUE if the reference count is one.
*/
BOOL IsUnique() const;
/**Make this instance to be the one and only reference to the container
contents. This implicitly does a clone of the contents of the container
to make a unique reference. If the instance was already unique then
the function does nothing.
@return
TRUE if the instance was already unique.
*/
virtual BOOL MakeUnique();
//@}
protected:
/**Constructor used in support of the Clone() function. This creates a
new unique reference of a copy of the contents. It does {\bf not}
create another reference.
The dummy parameter is there to prevent the contructor from being
invoked automatically by the compiler when a pointer is used by accident
when a normal instance or reference was expected. The container would
be silently cloned and the copy used instead of the container expected
leading to unpredictable results.
*/
PContainer(
int dummy, ///< Dummy to prevent accidental use of the constructor.
const PContainer * cont ///< Container class to clone.
);
/**Destroy the container contents. This function must be defined by the
descendent class to do the actual destruction of the contents. It is
automatically declared when the #PDECLARE_CONTAINER()# macro is used.
For all descendent classes not immediately inheriting off the PContainer
itself, the implementation of DestroyContents() should always call its
ancestors function. This is especially relevent if many of the standard
container classes, such as arrays, are descended from as memory leaks
will occur.
*/
virtual void DestroyContents() = 0;
/**Copy the container contents. This copies the contents from one reference
to another.
No duplication of contents occurs, for instance if the container is an
array, the pointer to the array memory is copied, not the array memory
block itself.
This function will get called by the base assignment operator.
*/
virtual void AssignContents(const PContainer & c);
/**Copy the container contents. This copies the contents from one reference
to another. It is automatically declared when the #PDECLARE_CONTAINER()#
macro is used.
No duplication of contents occurs, for instance if the container is an
array, the pointer to the array memory is copied, not the array memory
block itself.
This function will get called once for every class in the heirarchy, so
the ancestor function should {\bf not} be called.
*/
void CopyContents(const PContainer & c);
/**Create a duplicate of the container contents. This copies the contents
from one container to another, unique container. It is automatically
declared when the #PDECLARE_CONTAINER()# macro is used.
This class will duplicate the contents completely, for instance if the
container is an array, the actual array memory is copied, not just the
pointer. If the container contains objects that descend from #PObject#,
they too should also be cloned and not simply copied.
This function will get called once for every class in the heirarchy, so
the ancestor function should {\bf not} be called.
{\it {\bf Note well}}, the logic of the function must be able to
accept the passed in parameter to clone being the same instance as the
destination object, ie during execution #this == src#.
*/
void CloneContents(const PContainer * src);
/**Internal function called from container destructors. This will
conditionally call #DestroyContents()# to destroy the container contents.
*/
void Destruct();
class Reference {
public:
inline Reference(PINDEX initialSize)
: size(initialSize), count(1), deleteObjects(TRUE) { }
Reference(const Reference & ref)
: count(1)
{
#if PCONTAINER_USES_CRITSEC
PEnterAndLeave m(((Reference &)ref).critSec);
#endif
size = ref.size;
deleteObjects = ref.deleteObjects;
}
PINDEX size; // Size of what the container contains
PAtomicInteger count; // reference count to the container content - guaranteed to be atomic
BOOL deleteObjects; // Used by PCollection but put here for efficiency
#if PCONTAINER_USES_CRITSEC
PCriticalSection critSec;
#endif
private:
Reference & operator=(const Reference &)
{ return *this; }
} * reference;
};
/**Macro to declare funtions required in a container.
This macro is used to declare all the functions that should be implemented
for a working container class. It will also define some inline code for
some standard function behaviour.
This may be used when multiple inheritance requires a special class
declaration. Normally, the #PDECLARE_CONTAINER# macro would be used,
which includes this macro in it.
The default implementation for contructors, destructor, the assignment
operator and the MakeUnique() function is as follows:
\begin{verbatim}
cls(const cls & c)
: par(c)
{
CopyContents(c);
}
cls & operator=(const cls & c)
{
par::operator=(c);
return *this;
}
cls(int dummy, const cls * c)
: par(dummy, c)
{
CloneContents(c);
}
virtual ~cls()
{
Destruct();
}
BOOL MakeUnique()
{
if (par::MakeUnique())
return TRUE;
CloneContents(c);
return FALSE;
}
\end{verbatim}
Then the #DestroyContents()#, #CloneContents()# and #CopyContents()# functions
are declared and must be implemented by the programmer. See the
#PContainer# class for more information on these functions.
*/
#define PCONTAINERINFO(cls, par) \
PCLASSINFO(cls, par) \
public: \
cls(const cls & c) : par(c) { CopyContents(c); } \
cls & operator=(const cls & c) \
{ AssignContents(c); return *this; } \
virtual ~cls() { Destruct(); } \
virtual BOOL MakeUnique() \
{ if(par::MakeUnique())return TRUE; CloneContents(this);return FALSE; } \
protected: \
cls(int dummy, const cls * c) : par(dummy, c) { CloneContents(c); } \
virtual void DestroyContents(); \
void CloneContents(const cls * c); \
void CopyContents(const cls & c); \
virtual void AssignContents(const PContainer & c) \
{ par::AssignContents(c); CopyContents((const cls &)c); }
///////////////////////////////////////////////////////////////////////////////
// Abstract collection of objects class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -