Statistics
| Branch: | Revision:

root / include / cobject.h @ master

History | View | Annotate | Download (10.4 KB)

1 01873262 Georg Kunz
//==========================================================================
2
//  COBJECT.H - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//  Declaration of the following classes:
7
//    cObject : general base class
8
//
9
//==========================================================================
10
11
/*--------------------------------------------------------------*
12
  Copyright (C) 1992-2008 Andras Varga
13
  Copyright (C) 2006-2008 OpenSim Ltd.
14

15
  This file is distributed WITHOUT ANY WARRANTY. See the file
16
  `license' for details on this and other legal matters.
17
*--------------------------------------------------------------*/
18
19
#ifndef __COBJECT_H
20
#define __COBJECT_H
21
22
#include <string>
23
#include "simkerneldefs.h"
24
#include "simutil.h"
25
#include "cvisitor.h"
26
27
// Note: we include regmacros.h here in order to prevent the compiler from
28
// misunderstanding Register_Class() in other source files as a function declaration
29
#include "regmacros.h"
30
31
NAMESPACE_BEGIN
32
33
class cCommBuffer;
34
class cClassDescriptor;
35
class cOwnedObject;
36
37
38
/**
39
 * Root of the \opp class hierarcy. cObject is a lightweight class, it
40
 * does not contain any data members.
41
 *
42
 * Note: In OMNeT++ 2.x and 3.x, cObject was called cPolymorphic.
43
 * Class cObject in 2.x and 3.x has been renamed to cOwnedObject.
44
 *
45
 * It is recommended to use cObject as a base class for any class
46
 * that has at least one virtual member function. This makes the class more
47
 * interoperable with \opp, and causes no extra overhead at all.
48
 * sizeof(cObject) should yield 4 on a 32-bit architecture (4-byte vptr),
49
 * and using cObject as a base class does not add anything to the size
50
 * of an object, because a class with a virtual function already has a vptr.
51
 *
52
 * cObject allows the object to be displayed in graphical user
53
 * interface (Tkenv) via the getClassName(), info() and detailedInfo() methods
54
 * which you may choose to redefine in your own subclasses.
55
 *
56
 * Using cObject also strengthens type safety. <tt>cObject *</tt>
57
 * pointers should replace <tt>void *</tt> in most places where you need
58
 * pointers to "any data structure". Using cObject will allow safe
59
 * downcasts using <tt>dynamic_cast</tt> and also \opp's
60
 * <tt>check_and_cast</tt>.
61
 *
62
 * Any cObject may become owner of other objects, but owned objects must be
63
 * subclassed from cOwnedObject.
64
 *
65
 * Subclasses are expected to redefine member functions such as dup(),
66
 * info(), etc.
67
 *
68
 * @ingroup SimCore
69
 */
70
class SIM_API cObject
71
{
72
    friend class cOwnedObject;
73
    friend class cDefaultList;
74
75
  public:
76
    // internal: returns a descriptor object for this object
77
    virtual cClassDescriptor *getDescriptor();
78
79
  protected:
80
    // internal
81
    virtual void ownedObjectDeleted(cOwnedObject *obj);
82
83
    // internal
84
    virtual void yieldOwnership(cOwnedObject *obj, cObject *to);
85
86
  public:
87
    /**
88
     * Constructor. It has an empty body. (The class does not have data members
89
     * and there is nothing special to do at construction time.)
90
     */
91
    cObject() {}
92
93
    /**
94
     * Destructor. It has an empty body (the class does not have data members.)
95
     * It is declared here only to make the class polymorphic and make its
96
     * destructor virtual.
97
     */
98
    virtual ~cObject();
99
100
    /**
101
     * Returns a pointer to the class name string. This method is implemented
102
     * using typeid (C++ RTTI), and it does not need to be overridden
103
     * in subclasses.
104
     */
105
    virtual const char *getClassName() const;
106
107
    /** @name Empty virtual functions which can be redefined in subclasses */
108
    //@{
109
    /**
110
     * Returns pointer to the object's name. It should never return NULL.
111
     * This default implementation just returns an empty string ("").
112
     */
113
    virtual const char *getName() const  {return "";}
114
115
     /**
116
     * Returns true if the object's name is identical to the string passed.
117
     */
118
    bool isName(const char *s) const {return !opp_strcmp(getName(),s);}
119
120
    /**
121
     * When this object is part of a vector (like a submodule can be part of
122
     * a module vector, or a gate can be part of a gate vector), this method
123
     * returns the object's name with the index in brackets; for example:
124
     * "out[5]".
125
     *
126
     * This default implementation just returns getName().
127
     */
128
    virtual const char *getFullName() const  {return getName();}
129
130
    /**
131
     * Returns the full path of the object in the object hierarchy,
132
     * like "net.host[2].tcp.winsize". This method relies on getOwner():
133
     * if there is an owner object, this method returns the owner's fullPath
134
     * plus this object's fullName, separated by a dot; otherwise it simply
135
     * returns fullName.
136
     */
137
    virtual std::string getFullPath() const;
138
139
    /**
140
     * Can be redefined to produce a one-line description of object.
141
     * The string appears in the graphical user interface (Tkenv) e.g. when
142
     * the object is displayed in a listbox. The returned string should
143
     * possibly be at most 80-100 characters long, and must not contain
144
     * newline.
145
     *
146
     * @see detailedInfo()
147
     */
148
    virtual std::string info() const;
149
150
    /**
151
     * Can be redefined to produce a detailed, multi-line, arbitrarily long
152
     * description of the object. The string appears in the graphical
153
     * user interface (Tkenv) together with other object data (e.g. class name)
154
     * wherever it is feasible to display a multi-line string.
155
     */
156
    virtual std::string detailedInfo() const;
157
158
    /**
159
     * Should be redefined in subclasses to create an exact copy of this object.
160
     * The default implementation just throws an error, to indicate that
161
     * the method was not redefined.
162
     */
163
    virtual cObject *dup() const;
164
    //@}
165
166
  protected:
167
    /** @name Ownership control.
168
     *
169
     * The following functions are intended to be used by derived container
170
     * classes to manage ownership of their contained objects.
171
     * See object description for more info on ownership management.
172
     */
173
    //@{
174
175
    /**
176
     * Makes this object the owner of 'object'.
177
     * The function called by the container object when it takes ownership
178
     * of the obj object that is inserted into it.
179
     *
180
     * The obj pointer should not be NULL.
181
     */
182
    virtual void take(cOwnedObject *obj);
183
184
    /**
185
     * Releases ownership of `object', giving it back to its default owner.
186
     * The function called by the container object when obj is removed
187
     * from the container -- releases the ownership of the object and
188
     * hands it over to its default owner.
189
     *
190
     * The obj pointer should not be NULL.
191
     */
192
    virtual void drop(cOwnedObject *obj);
193
194
    /**
195
     * This is a shortcut for the sequence
196
     * <pre>
197
     *   drop(obj);
198
     *   delete obj;
199
     * </pre>
200
     *
201
     * It is especially useful when writing destructors and assignment operators.
202
     *
203
     * Passing NULL is allowed.
204
     *
205
     * @see drop()
206
     */
207
    void dropAndDelete(cOwnedObject *obj);
208
    //@}
209
210
  public:
211
    /** @name Support for parallel execution.
212
     *
213
     * These functions pack/unpack the object from/to a communication buffer,
214
     * and should be redefined in classes whose instances are expected to
215
     * travel across partitions.
216
     */
217
    //@{
218
    /**
219
     * Serializes the object into a buffer.
220
     */
221
    virtual void parsimPack(cCommBuffer *buffer);
222
223
    /**
224
     * Deserializes the object from a buffer.
225
     */
226
    virtual void parsimUnpack(cCommBuffer *buffer);
227
    //@}
228
229
    /** @name Miscellaneous functions. */
230
    //@{
231
    /**
232
     * May be redefined to return an owner or parent object. This default
233
     * implementation just returns NULL.
234
     */
235
    virtual cObject *getOwner() const {return NULL;}
236
237
    /**
238
     * Returns true if this class is a subclass of cOwnedObject.
239
     * This is a performance optimization, to avoid frequent calls to
240
     * dynamic_cast\<\>. In cObject this method returns false, in
241
     * cOwnedObject it returns true, and it MUST NOT be defined on
242
     * any other class.
243
     */
244
    virtual bool isOwnedObject() const {return false;}
245
246
    /**
247
     * Enables traversing the object tree, performing some operation on
248
     * each object. The operation is encapsulated in the particular subclass
249
     * of cVisitor.
250
     *
251
     * This method should be redefined in every subclass to call v->visit(obj)
252
     * for every obj object contained.
253
     */
254
    virtual void forEachChild(cVisitor *v);
255
256
    /**
257
     * Finds the object with the given name. This function is useful when called
258
     * on subclasses that are containers. This method
259
     * finds the object with the given name in a container object and
260
     * returns a pointer to it or NULL if the object has not
261
     * been found. If deep is false, only objects directly
262
     * contained will be searched, otherwise the function searches the
263
     * whole subtree for the object. It uses the forEachChild() mechanism.
264
     *
265
     * Do not use it for finding submodules! Use cModule::getModuleByRelativePath()
266
     * instead.
267
     */
268
    cObject *findObject(const char *name, bool deep=true);
269
    //@}
270
271
    /** @name Helper functions. */
272
    //@{
273
    /**
274
     * Convenience function: throws a cRuntimeError ("copying not supported")
275
     * stating that assignment, copy constructor and dup() will not work
276
     * for this object. You can call this from operator=() if you do not want to
277
     * implement object copying.
278
     */
279
    void copyNotSupported() const;
280
    //@}
281
};
282
283
284
/**
285
 * Utility class, to make it impossible to call the operator= and copy
286
 * constructor of any class derived from it.
287
 *
288
 * NOTE: <tt>dup()</tt> must be redefined as <tt>{copyNotSupported(); return NULL;}</tt>
289
 * in classes directly subclassing from noncopyable, but this is not needed
290
 * in classes derived from them. For example, cDefaultList is noncopyable,
291
 * so cModule, cCompoundModule and cSimpleModule no longer need to redefine
292
 * <tt>dup()</tt>.
293
 *
294
 * This class is from boost, which bears the following copyright:
295
 *
296
 * (C) Copyright Boost.org 1999-2003. Permission to copy, use, modify, sell
297
 * and distribute this software is granted provided this copyright
298
 * notice appears in all copies. This software is provided "as is" without
299
 * express or implied warranty, and with no claim as to its suitability for
300
 * any purpose.
301
 */
302
class noncopyable
303
{
304
  protected:
305
    noncopyable() {}
306
    ~noncopyable() {}
307
  private:
308
    // private, and in addition unimplemented (usage causes missing linker symbol)
309
    noncopyable(const noncopyable& x);
310
    const noncopyable& operator=(const noncopyable&);
311
};
312
313
NAMESPACE_END
314
315
316
#endif