text:
Chapter 5 Semantics of Construction, Destruction, and Copy Consider the following abstract base class declaration: class Abstract_base { public : virtual ~Abstract_base()=0; virtual void interface()const=0; virtual const char* mumble () const { return _mumble; } protected: char *_mumble;}; Do you see any problems? Although the class is designed to serve as an abstract base class (the presence of a pure virtual function disallows independent instances of Abstract_base to be created), the class still requires an explicit constructor in order to initialize its one data member, _mumble. Without that initialization, a local o b j e c t of a class de ri ve d from Abstract_base will have its instance of __mumble uninitialized. For example: class Concrete_derived : public Abstract_base { public : Concrete_derived(); //. . . }; void f o o ( ) { // Abstract_base::_mumble uninitialized Concrete_derived trouble; //. . . }; One might argue that the designer of Abstract_base intended for each class derived from it to provide a first value for _mumble. However, if that's the case, the only way to require that of the derived class is to provide a protected Abstract_base constructor that takes one argument: Abstract_Base:: Abstract_Base(char *mumble_value=0):_ _murable(mumble_value){} In general, the data members of a class should be initialized and assigned to only within the constructor and other member functions of that class. To do otherwise breaks encapsulation, thereby making maintenance and modification of the class more difficult. Alternatively, one might argue that the design error is not the absence of an explicit constructor, but rather the declaration of a data member within an abstract base class. This is a stronger argument (separating interface and implementation), but it does not hold universally. Lifting up data members shared among several derived types can be a legitimate design choice. Presence of a Pure Virtual Destructor Programmers new to C++ are often surprised to learn that one may both define and invoke a pure virtual function, provided it is invoked statically and not through the virtual mechanism. For example, one can legally code the following: // ok: definition of pure virtual function // but may only be invoked statically . inline void Abstract_base::interface() { //. . . } inline void Concrete_derived::interface() { // ok: static invocation Abstract_base::interface(); }; Whether one does so is a decision left to the class designer in all but one instance. The exception is a pure virtual destructor: It must be defined by the class designer. Why? Every derived class destructor is internally augmented to statically invoke each of its virtual base and immediate base class destructors. The absence of a definition of any of the base class destructors in general results in a link-time error. One could argue, shouldn't the invocation of a pure virtual destructor be suppressed by the compiler during the augmentation of the destructor of the derived class? No. The class designer may actually have defined an instance of the pure virtual destructor (just as Abstract_base:: interface() is defined in the previous example). The design itself may depend on the language's guarantee that each destructor within the hierarchy of a class object is invoked. The compiler cannot suppress the call. But one then could argue, shouldn't the compiler know enough to synthesize the definition of the pure virtual destructor if the designer of the class either forgot or did not know it needed to be defined? No. The compiler by itself can't know that because of the separate compilation model of an executable. An environment may provide a facility to discover the absence at link time and to reinvoke the compiler with a directive to synthesize an instance, but I am not aware of any current implementation that does so. A better design alternative is to not declare a virtual destructor as pure. Presence of a Virtual Specification Abstract_base::mumble_set() is a bad choice for a virtual function because its algorithm is not type dependent and is therefore highly unlikely to be overridden by a subsequent derived class. Moreover, because its nonvirtual implementation is inline, the performance penalty may be significant if it is frequently invoked. However, couldn't a compiler, through analysis, determine that only a single instance of the function exists within the class hierarchy. In so doing, could it not transform the call into a static invocation, thereby allowing for the inline expansion of the call? But what happens if the hierarchy is subsequently added to and the new class introduces a new instance of the function? This new class invalidates the optimization. The function must now be recompiled (or perhaps a second, polymorphic instance generated, with the compiler determining through flow analysis which instance needs to be invoked). The function, however, may exist as a binary within a library. Unearthing this dependency is likely to require some form of persistent program database or library manager. In general, it is still a bad design choice to declare all functions virtual and to depend on the compiler to optimize away unnecessary virtual invocations. Presence of const within a Virtual Specification Determining the const-ness of a virtual function may seem rather trivial, but in practice it is not easy to do within an abstract base class. Doing so means predicting the usage of a potentially infinite number of subclass implementations. Not declaring a function const means the function cannot be called by a const reference or const pointer argument—at least not without resorting to a casting away of the const. Considerably more problematic is declaring a function const and then discovering that, in practice, a derived instance really does need to modify a data member. I don't know of a generally agreed upon approach, but I can bear witness to the problem. In my code, I tend toward leaving off the const. A Reconsidered Class Declaration The previous discussion suggests that the following redeclaration of Abstract_base would seem the more appropriate design: class Abstract_base { public: virtual ~Abstract_base(); virtual void interface() = 0; const char* mumble () const { return _mumble; } protected: Abstract_base( char *pc = 0 ) char *_mumble;}; 5.1 Object Construction without Inheritance Consider the following generic program fragment: (1) Point global; (2) (3) Point foobar() (4) { (5) Point local; (6) Point *heap = new Point; (7) *heap = local; (8) // ... stuff ... (9) delete heap; (10)return local; (11)} Lines 1, 5, and 6 represent the three varieties of object creation: global, local, and heap memory allocation. Line 7 represents the assignment of one class object with another, while line 10 represents the initialization of the return value with the local Point object. Line 9 explicitly deletes the heap object. The lifetime of an object is a runtime attribute of an object. The local object's lifetime extends from its definition at line 5 through line 10. The global object's lifetime extends for the entire program execution. The lifetime of an object allocated on the heap extends from the point of its allocation using operator new through application of operator delete. Here is a first declaration of Point, written as it might be in C. The Standard speaks of this Point declaration as Plain Ol' Data. typedef struct { float x, y, z; } Point; What happens when this declaration is compiled under C++? Conceptually, a trivial default constructor, trivial destructor, trivial copy constructor, and trivial copy assignment operator are internally declared for Point. In practice, all that happens is that the compiler has analyzed the declaration and tagged it to be Plain Ol' Data. When the compiler encounters the definition (1) Point global; then conceptually, the definition of both Point's trivial constructor and destructor are generated and invoked (the constructor at program startup and the destructor usually within the system-generated call to exit() upon completion of main ()). In practice, however, these trivial members are neither defined nor invoked, and the program behaves exactly as it would in C. Well, with one minor exception. In C, global is treated as a tentative definition because it is without explicit initialization. A tentative definition can occur multiple times within the program. Those multiple instances are collapsed by the link editor, and a single instance is placed within the portion of the program data segment reserved for uninitialized global objects (for historical reasons, it's called the BSS, an abbreviation of Block Started by Symbol, an IBM 704 assembler pseudo-op). In C++, tentative definitions are not supported because of the implicit application of class constructors. (Admittedly the language could have distinguished between class objects and Plain Ol' Data, but doing so seemed an unnecessary complication.) global, therefore, is treated within C++ as a full definition (precluding a second or subsequent definition). One difference between C and C++, then, is the relative unimportance of the BSS data segment in C++. All global objects within C++ are treated as initialized. The local Point object within foobar() on line 5 is similarly neither constructed nor destructed. Of course, leaving the local Point object uninitialized is a potential program bug if a first use depends on its being set, such as on line 7. The initialization of heap on Line 6 (6) Point *heap = new Point; is transformed into a call of the library instance of operator new Point *heap = _new( s i z e o f ( Point ) ) ; Again, there is no default constructor applied to the Point object returned by the call to operator new. The assignment to this object on the next line would solve this problem if local were properly initialized: (7) *heap = local; This assignment should generate a compiler warning of the general form warning, line 7: local is used before being initialized. Conceptually, this assignment triggers the definition of the trivial copy assignment operator, which is then invoked to carry out the assignment. Again, in practice, since the object is Plain Ol' Data, the assignment remains a bitwise copy exactly as it is in C. The deletion of heap on Line 9 (9) delete heap; is transformed into a call of the library instance of operator delete _delete( heap ) ; Again, conceptually, this triggers the generation of the trivial destructor for Point. But, as we've seen, the destructor, in practice, is neither generated nor invoked. Finally, the return of local by value conceptually triggers the definition of the trivial copy constructor, which is then invoked, and so on. In practice, the return remains a simple bitwise operation of Plain Ol' Data. Abstract Data Type The second declaration of Point provides full encapsulation of private data behind a public interface but does not provide any virtual function interface: class Point { public: Point( float x = 0 .0 , float y = 0.0 , float z = 0.0 ) : _x( x ), _y( y ), _z( z ) {} //no copy constructor, copy operator // or destructor defined ... / / . . . private: float _x, _y, _ z ; } ; The size of an encapsulated Point class object remains unchanged: the three contiguous coordinate float members. Neither the private nor public access labels nor the member function declarations take up any space within the object. We do not define either a copy constructor or copy operator for our Point class because the default bitwise semantics are sufficient. Nor do we provide a destructor; the default program management of memory is sufficient. The definition of a global instance Point global; //apply Point::Point(0 . 0 , 0.0, 0.0); now has the default constructor applied to it. Since global is defined at global scope, its initialization needs to be deferred until program startup (see Section 6.1 for a full discussion). In the special case of initializing a class to all constant values, an explicit initialization list is slightly more efficient than the equivalent inline expansion of a constructor, even at local scope (although at local scope, this may seem slightly nonintuitive. You'll see some numbers on this in Section 5.4). For example, consider the following code fragment: void mumble() { Pointl local1 = { 1 . 0 , 1 . 0 , 1.0 }; Point2 local2; // equivalent to an inline expansion // the explicit initialization is slightly faster local2._x = 1 . 0 ; local2._y = 1 . 0 ; local2._z = 1 . 0 ; }; local1's initialization is slightly more efficient than that of local2's. This is because the values within the initialization list can be placed within local1's memory during placement of the function's activation record upon the program stack. There are three drawbacks of an explicit initialization list: 1. It can be used only if all the class members are public. 2. It can specify only constant expressions (those able to be evaluated at compile time). 3. Because it is not applied automatically by the compiler, the likelihood of failure to initialize an object is significantly heightened. As a result, can the use of an explicit initialization list provide a performance increase significant enough to compensate for its software engineering drawbacks? In general, no. In practice, however, it can make a difference in certain special cases. For example, perhaps you are hand-building some large data structure, such as a color palette, or you are dumping into program text large amounts of constant values, such as the control ver- tices and knot values of a complex geometric model created in a package such as Alias or Softlmage. In these cases, an explicit initialization list performs better than an inline constructor, particularly for global objects. At the compiler level, a possible optimization would be recognition of inline constructors that simply provide a member-by-member assignment of constant expressions. The compiler might then extract those values. It would treat them the same as those supplied in an explicit initialization list, rather than expanding the constructor as a sequence of assignment statements. The definition of the local Point object { //. . . Point local; } is now followed by the inline expansion of the default Point constructor: // inline expansion of default constructor Point local; local. _x = 0 . 0 ; local. _y = 0 . 0 ; local. _z = 0.0; The allocation of the Point object on the heap on line 6 (6) Point *heap = new Point; now includes a conditional invocation of the default Point constructor // Pseudo C++ Code Point *heap = _ new( sizeof ( Point ) ) ; if ( heap != 0 ) heap->Point : : Point ( ) ; which is then inline expanded. The assignment of the local object to the object pointed to by heap (7) *heap = local; remains a simple bitwise copy, as does the return of the local object by value: ( 1 0 ) return local; The deletion of the object addressed by heap (9) delete heap; does not result in a destructor call, since we did not explicitly provide an instance. Conceptually, our Point class has an associated default copy constructor, copy operator, and destructor. These, however, are trivial and are not in practice actually generated by the compiler. Preparing for Inheritance Our third declaration of Point prepares for inheritance and the dynamic resolution of certain operations, in this case limited to access of the coordinate member, z: class Point public: Point ( float x = 0 . 0 , float y = 0 . 0 ) : _x( x ), _y( y ) {} // no destructor, copy constructor, or // copy operator defined . . . virtual float z(); // . . . protected: float _x, __y; }; We again do not define a copy constructor, copy operator, or destructor. All our members are stored by value and are therefore well behaved on a program level under the default semantics. (Some people would argue that the introduction of a virtual function should always be accompanied by the declaration of a virtual destructor. But doing that would buy us nothing in this case.) The introduction of the virtual function triggers the addition of a virtual table pointer within each Point object. This provides us with the flexibility of a virtual interface, but at the cost of additional word of storage per object. How significant is this? Clearly that depends on the application and general domain. In the 3D modeling domain, if you were to represent a complex geometric shape that has 60 NURB surfaces with 512 control vertices per surface, the 4-byte overhead per Point object would approach 200,000 bytes. This may or may not be significant. Whether it was would have to be weighed against the practical benefits of polymorphism in the design. What you want to avoid is becoming aware of the issue only after the implemen- tation is complete. In addition to the vptr added within each class object, the introduction of the virtual function causes the following compiler-driven augmentations to our Point class: • The constructor we've defined has code added to it to initialize the virtual table pointer. This code has to be added after the invocation of any base class constructors but before execution of any user- supplied code. For example, here is a possible expansion of our Point constructor: // Pseudo C + + Code: internal augmentation Point* Point::Point( Point *this, float x, float y ) : _ _x { x ) , __y( y ) { // set the o b j e ct ' s virtual table pointer this->_vptr_Point = _vtbl_Point; // expand member initialization list this->_x= x; this->_y = y; // return this object . . . return this; }; Both a copy constructor and a copy operator need to be synthesized, as their operations are now nontrivial. (The implicit destructor remains trivial and so is not synthesized.) A bitwise operation might otherwise result in an invalid setting of the vptr if a Point object is initialized or assigned with a derived class object. // Pseudo C++ Code: // internal synthesis of copy constructor inline Point* Point::Point( Point *this, const Point &rhs ) { //set the object's virtual table pointer this->__vptr_Point = _vtbl_Point; // `bitblast' contiguous portion of rhs' // coordinates into this object or provide / / a member by member assignment . . . return this;}; The compiler, in an optimization, may copy contiguous chucks of one object into another rather than implement a strict memberwise assignment. The Standard requires implementations to defer the actual synthesis of these nontrivial members until an actual use is encountered. As a convenience, I've reproduced foobar() here: (1)Point global; (2) (3)Point foobar() (4){ (5)Point local; (6)Point *heap = new Point; (7)*heap = local; (8)// ... stuff ... (9)delete heap; (10)return local; (11)} The initialization of global on line 1, the initialization of heap on line 6, and the deletion of heap on line 9 remain exactly the same as for the earlier representation of Point. The memberwise assignment, however, of line 7 *heap = local; is likely to trigger the actual synthesize of the copy assignment operator and an inline expansion of its invocation, substituting heap for the this pointer and local for the rhs argument. The most dramatic impact on our program is the return of local by value on line 10. In the presence of the copy constructor, foobar() is likely to be transformed as follows (this is discussed in greater detail in Section 2.3): // Pseudo C++ code: transformation of foobar() / / t o support copy construction void foobar( Point &_result ) { Point local; local.Point::Point( 0 . 0 , 0.0 ); // heap remains the same ... // application of copy constructor _result.Point::Point( local ); // destruction of local object would go here // had Point defined a destructor: // local.Point::~Point( ) ; return;} And if the named return value (NRV) optimization is supported, the function is further transformed as follows: // Pseudo C++ code: transformation of foobar() // to support named return value optimization void foobar( Point &_result ) { _result.Point::Point( 0. 0, 0.0 ); // heap remains the same ... return; In general, if your design includes a number of functions requiring the definition and return of a local class object by value, such as arithmetic operations of the form T operator+( const T&, const T&) { T result; / / ... actual work return result; }; then it makes good sense to provide a copy constructor even if the default memberwise semantics are sufficient. Its presence triggers the application of the NRV optimization. Moreover, as I showed in the previous example, its application removes the need for invoking the copy constructor, since the results are being directly computed within the object to be returned. 5.2 Object Construction under Inheritance When we define an object, such as T object; exactly what happens? If there is a constructor associated with T (either user supplied or synthesized by the compiler), it is invoked. That's obvious. What is sometimes less obvious is what the invocation of a constructor actually entails. Constructors can contain a great deal of hidden program code because the compiler augments every constructor to a greater or lesser extent depending on the complexity of T's class hierarchy. The general sequence of compiler augmentations is as follows: 1. The data members initialized in the member initialization list have to be entered within the body of the-constructor in the order of member declaration. 2. If a member class object is not present in the member initialization list but has an associated default constructor, that default constructor must be invoked. 3. Prior to that, if there is a virtual table pointer (or pointers) contained within the class object, it (they) must be initialized with the address of the appropriate virtual table(s). 4. Prior to that, all immediate base class constructors must be invoked in the order of base class declaration (the order within the member initialization list is not relevant). • If the base class is listed within the member initialization list, the explicit arguments, if any, must be passed. • If the base class is not listed within the member initialization list, the default constructor (or default memberwise copy constructor) must be invoked, if present. • If the base class is a second or subsequent base class, the this pointer must be adjusted. 5. Prior to that, all virtual base class constructors must be invoked in a left-to-right, depth-first search of the inheritance hierarchy defined by the derived class. • If the class is listed within the member initialization list, the explicit arguments, if any, must be passed. Otherwise, if there is a default constructor associated with the class, it must be invoked. • In addition, the offset of each virtual base class subobject within the class must somehow be made accessible at runtime. • These constructors, however, may be invoked if, and only if, the class object represents the "most-derived class." Some mechanism supporting this must be put into place. In this section, I consider the augmentations necessary to constructors in order to support the language- guaranteed semantics of the class. I again illustrate the discussion with the help of a Point class. (I added a copy constructor, copy operator, and virtual destructor in order to illustrate the behavior of subsequent containing and derived classes in the presence of these functions.) class Point { public: Point( float x = 0 . 0 , float y = 0 . 0 ); Point( const Point& ); Point& operator=( const Points ); virtual ~Point(); virtual float z(){ return 0 . 0 ; } // . . . protected: float _x, _y; }; Before I introduce and step through an inheritance hierarchy rooted in Point, I'll quickly look at the declaration and augmentation of a class Line, which is composed of a begin and end point: class Line { Point _begin, _end; public: Line( float=0.0, float=0.0, float=0.0, float=0.0 ); Line{ const Point&, const Points ); draw ( ) ; //. . . }; Each explicit constructor is augmented to invoke the constructors of its two member class objects. For example, the user constructor Line::Line( const Point kbegin, const Point &end ) : _end ( end ) , __begin ( begin ) {}; is internally augmented and transformed into // Pseudo C++ Code: Line constructor augmentation Line* Line::Line( Line *this, const Point &begin, const Point &end ) { this->_begin.Point::Point( begin ) ; this->_end.Point::Point( end ); return this;}; Since the Point class declares a copy constructor, a copy operator, and a destructor (virtual in this case), the implicit copy constructor, copy operator, and destructor for Line are nontrivial. When the programmer writes Line a; the implicit Line destructor is synthesized. (If Line were derived from Point, the synthesized destructor would be virtual. However, because Line contains only Point objects, the synthesized Line destructor is nonvirtual). Within it, the destructors for its two member class objects are invoked in the reverse order of their construction: // Pseudo C++ Code: Line destructor synthesis inline void Line::~Line( Line *this ) { this->_end.Point::~Point(); this->_begin.Point::~Point(); }; Of course, if the Point destructor is inline, each invocation is expanded at the point of call. Notice that although the Point destructor is virtual, its invocation within the containing class destructor is resolved statically. Similarly, when the programmer writes Line b = a; the implicit Line copy constructor is synthesized as an inline public member. Finally, when the programmer writes a = b; the implicit copy assignment operator is synthesized as an inline public member. While poking around cfront recently, I noticed that when generating the copy operator, it does not condition the copy by a guard of the form if ( this == &rhs ) return *this; As a result, it applies redundant copying for expressions such as Line *pl = &a; Line *p2 = &a; *pl = *p2; This is not unique to cfront, I discovered; Borland also leaves off a guard, and I suspect this is true of most compilers. In the case of a compiler-synthesized copy operator, the duplication is safe but redundant, since no deallocation of resources is involved. Failure to check for an assignment to self in a user-supplied copy operator is a common pitfall of the beginner programmer; for example, // User supplied copy assignment operator // forgets to provide a guard against self -copy Strings String::operator=(const String &rhs ) { // need guard here before deallocate resources delete [] str; str = new char[strlen(rhs.str)+1]; //. . . }; Under the category of good intentions not acted upon, I had many times thought of adding a warning message to cfront for the case when, within a copy operator, the operator lacked a guard against self-copy but contained a delete operator upon one of its members. I still think a message warning of this would be useful to the programmer. Virtual Inheritance Consider the following virtual derivation from our Point class: class Point3d : public virtual Point { public: Point3d( float x = 0 . 0, float y = 0 . 0 , float z = 0 . 0 ) : Point( x, y ), _z( z ) {}; Point3d( const Point3d& r h s ) : Point( rhs ), _z(rhs._z) {}; ~ Poi nt 3d() ; Point3d& operator=( const Point3d& ); virtual float z ( ) { return _z; } // . . . protected: f l o a t _ z; }; The conventional constructor augmentation does not work due to the shared nature of the virtual base class: // Pseudo C + + Code: // Invalid Constructor Augmentation Point3d* Point3d::Point3d (Point3d *this, f l o a t x, f l o a t y, float z ){ this->Point::Point( x, y ); this->_vptr_Point3d=_vtbl_Point3d; this->__vptr_Point3d_Point=_vtbl_Point3d_Point; this->_z = rhs._z; return this;} Do you see what's wrong with this augmentation of the Point3d constructor? Consider the following three class derivations: class Vertex : virtual public Point { . . . }; class Vertex3d : public Point3d, public Vertex { }; class PVertex : public Vertex3d { . . . }; The constructor for Vertex must also invoke the Point class constructor. However, when Point3d and Vertex are subobjects of Vertex3d, their invocations of the Point constructor must not occur; rather, Vertex3d, as the most- derived class, becomes responsible for initializing Point. In the subsequent PVertex derivation, it, not Vertex3d, is responsible for the initialization of the shared Point subobject. The traditional strategy for supporting this sort of "now you initialize the virtual base class, now you don't" is to introduce an additional argument in the constructor(s) indicating whether the virtual base class constructor(s) should be invoked. The body of the constructor conditionally tests this argument and either does or does not invoke the associated virtual base class constructors. Here is this strategy of Point3d constructor augmentation: // Psuedo C++ Code: // Constructor Augmentation with Virtual Base class Point3d* Point3d::Point3d( Point3d *this, bool _most_derived, f l o a t x, float y, float z ) { if ( _most_derived != false ) this->Point::Point( x, y); this->vptr_Point3d = _vtbl_Point3d; this->vptr_Point3d_Point=_vtbl_Point3d_Point; this->_z = rhs._z; return this; }; Within a subsequently derived class, such as Vertex3d, the invocation of the Point3d and Vertex constructors always sets the _most_derived argument to false, thus suppressing the Point constructor invocation within both constructors. // Psuedo C + + Code: // Constructor Augmentation with Virtual Base class Vertex3d* Vertex3d::Vertex3d( Vertex3d *this, bool _most_derived, float x, float y, float z ) if ( _most_derived != false ) this->Point::Point( x, y); // invoke immediate base classes, // setting _most_derived to false this->Point3d::Point3d( false, x, y, z ); this->Vertex::Vertex( false, x, y ); // set vptrs // insert user code return this;} This strategy gets the semantics right. For example, when we define Point3d origin; the Point3d constructor correctly invokes its Point virtual base class subob-ject. When we define Vertex3d cv; the Vertex3d constructor correctly invokes the Point constructor. The Point3d and Vertex constructors do everything but that invocation. So, if the behavior is right, then what's wrong? A number of us have noticed that the conditions under which the virtual base class constructors are invoked is well defined. They are invoked when a complete class object is being defined, such as origin; they are not invoked when the object serves as a subobject of an object of a subsequently derived class. Leveraging this knowledge, we can generate better-performing constructors at the expense of generating more program text. Some newer implementations split each constructor into a complete object and a subobject instance. The complete object version unconditionally invokes the virtual base constructors, sets all vptrs, and so on. The subobject version does not invoke the virtual base class constructors, may possibly not set the vptrs, and so on. (I look at the issue of setting the vptr in the next section.) This splitting of the constructor should result in considerable program speed up. Unfortunately, I do not have access to a compiler that actually does this and so have no numbers to confirm this. (During the Foundation project, however, Rob Murray, out of frustration I suspect, hand-optimized cfront's C output to elide unnecessary conditional tests and the setting of the vptr. He reported a measurable speed up.) The Semantics of the vptr Initialization When we define a PVertex object, the order of constructor calls is Point( x, y ) ; Point3d( x, y, z ) ; Vertex( x, y, z ); Vertex3d( x, y, z ); PVertex(x, y, z ) ; Assume each class within its hierarchy defines an instance of a virtual function size() that returns the size in bytes of the class. For example, if we were to write PVertex pv; Point3d p3d; Point *pt = &pv; the call pt->size(); would return the size of the PVertex class and pt = &p3d; p t - >s i ze (); would return the size of the Point3d class. Further assume that each constructor within the class hierarchy contains an invocation of size(). For example, Point3d::Point3d( float x, float y, float z ) : _x ( x ) , _y ( y ) , _z ( z ) { if ( spyOn ) cerr « "within Point3d: :Point3d()" « " size: " « size() « endl; } When we define our PVertex object, what should the outcome of the five constructor calls look like? Should each invocation of size() resolve to PVertex::size() (that's what we're constructing, after all)? Or should each invocation resolve to the associated s i z e () instance of the class whose constructor is currently executing? The language rule is that inside the Point3d constructor, the invocation of size() must resolve to the Point3d instance, not the PVertex instance. More generally, within the constructors (and destructor) of a class (in this case, our Point3d class), the invocation of a virtual function by the object under construction (in this case, our PVertex object) is limited to the virtual functions active within the class (that is, our Point3d class). This is necessary because of the class order of constructor invocation: Classes are built from the bottom up and then the inside out. As a result, the derived instance is not yet constructed while the base class constructor executes. The PVertex object is not a complete PVertex object until the completion of its constructor. While the Point3d constructor executes, only its Point3d subobject is yet constructed. This means that as each of the PVertex base class constructors are invoked, the compilation system must guarantee that the appropriate instance of size() is invoked. How might that be done? Were invocations limited to direct calls from within the constructor (or destructor), the solution would be reasonably straightforward: Simply resolve each call statically, never invoking the virtual mechanism. Within the Point3d constructor, for example, explicitly invoke Point3d::size(). What happens, however, if within size() a subsequent virtual function call occurs? In this case, that call too must resolve to the Point3d instance. In other cases, however, the call is genuinely virtual and must go through the virtual mechanism. That is, somehow we must "sensitize" the virtual mechanism itself to be aware of whether the call is originating from within a constructor. One way we could do that, I suppose, is to set a flag from within the constructor (or destructor) saying essentially, "Hey, no, this time resolve the call statically." We could then generate conditional invocations based on the state of the flag. This would work, although it feels both inelegant and inefficient—a good example of a hack. We could even cover ourselves with a program source comment such as // yuck!!! f i x the language semantics! This solution feels more like a response to the failure of our first design strategy than a solution to the underlying problem, that is, the need- to constrain the set of candidate virtual functions to be considered during execution of a constructor. Consider for a moment what actually determines the virtual function set active for a class: the virtual table. How is that virtual table accessed and thus the active set of virtual functions determined? By the address to which the vptr is set. So to control the set of active functions for a class, the compilation system need simply control the initialization and setting of the vptr. (It is the compiler's responsibility to set the vptr, of course, not something the programmer need or should worry about.) How should the vptr initialization be handled? Essentially, this depends on when the vptr should be initialized within the constructor. There are three choices: 1. First, before anything else happens 2. After invocation of the base class constructors but before execution of user-provided code or the expansion of members initialized within the member initialization list 3. Last, after everything else has happened The answer is after the invocation of the base class constructors. The other two choices do nothing. If you don't believe that, work through the invocation of size() under strategy 1 or 3. Strategy 2 solves the problem of constraining the set of candidate virtual functions within the class. If each constructor waits to set its object's vptr until after its base class constructors have executed, then the correct instance of the virtual function is invoked each time. By having each base class constructor set its object's vptr to the virtual table associated with its class, the object under construction literally becomes an object of that class for the duration of the constructor. That is, a PVertex object in turn becomes a Point object, a Point3d object, a Vertex object, a Vertex3d object, and then a PVertex object. Within each base class constructor, the object is indistinguishable from a complete object of the constructor's class. For objects, ontogeny recapitulates phylogeny. The general algorithm of constructor execution is as follows: 1. Within the derived class constructor, all virtual base class and then immediate base class constructors are invoked. 2. That done, the object's vptr(s) are initialized to address the associated virtual table(s). 3. The member initialization list, if present, is expanded within the body of the constructor. This must be done after the vptr is set in case a virtual member function is called. 4. The explicit user-supplied code is executed. For example, given the following user-defined PVertex constructor: PVertex::PVertex( float x, float y, float z ) : _next( 0 }, Vertex3d( x, y, z ), Point( x, y ) { if ( spyOn ) cerr « "within Point3d::Point3d()" « " size: " « s i z e () « endl; }; a likely internal expansion would look something like this: // Pseudo C++ Code // expansion of PVertex constructor PVertex* PVertex::PVertex( Pvertex* this, bool _most_derived, float x, float y, float z ) / // conditionally invoke the virtual base constructor if(most_derived != false ) this->Point::Point( x, y ); // unconditional invocation of immediate base this->Vertex3d::Vertex3d( x, y, z ); // initialize associated vptrs this->__vptr_PVertex = _vtbl_PVertex; this->__vptr_Point_PVertex=_vtbl_Point_PVertex; // explicit user code if ( spyOn ) cerr « "within Point3d::Point3d()" « " size: " // invocation through virtual mechanism « (*this->__vptr_Pvertex[3].faddr)(this) « endl; // return constructed object return this; }; This resolves our stated problem of constraining the virtual mechanism perfectly. But, is it a perfect solution? Suppose our Point constructor is defined as Point::Point( float x, f l o a t y ) : _x( x ), _y( y ){} and our Point3d is defined as Point3d::Point3d( float x, float y, float z ) : Point( x, y ), _z( z ){} Further suppose our Vertex and Vertex3d constructors are defined in a similar manner. Do you see how our solution is less than perfect even though we've solved our problem perfectly? There are two conditions under which the vptr must be set: 1. When a complete object is being constructed. If we declare a Point object, the Point constructor must set its vptr. 2. When, within the construction of a subobject, a virtual function call is made either directly or indirectly If we declare a PVertex object, then because of our latest definitions of its base class constructors, its vptr is needlessly being set within each base class constructor. The solution is to split the constructor into a complete boject instance and a subobject instance. In the subobject instance, the setting of the vptr is elided if possible. Given what we know, you should be able to answer the following question: Is it safe to invoke a virtual function of the class within its constructor's member initialization list? Physically, it is always safe when the function is applied to the initialization of a data member of the class. This is because, as we've seen, the vptr is guaranteed to have been set by the compiler prior to the expansion of the member initialization list. It may not be semantically safe, however, because the function itself may depend on members that are not yet initialized. It is not an idiom I recommend. However, from the point of view of the integrity of the vptr, it is a safe operation. What about when providing an argument for a base class constructor? Is it still physically safe to invoke a virtual function of the class within its constructor's member initialization list? No. The vptr is either not set or set to the wrong class. Further, any of the data members of the class that are accessed within the function are guaranteed to not yet be initialized. 5.3 Object Copy Semantics When designing a class, we have three choices regarding the assignment of one class object with another: 1. Do nothing, thereby allowing for the default behavior. 2. Provide an explicit copy assignment operator. 3. Explicitly disallow the assignment of one class object with another. Disallowing the copying of one class object with another is accomplished by declaring the copy assignment operator private and not providing a definition. (By making it private, we disallow assignment everywhere except within member functions and friends of the class. By our not providing a definition, then if a member function or friend were to attempt to effect a copy, the program would fail to link. Admittedly, having to depend on properties of the linker — that is, on properties outside of the language itself — is not fully satisfactory.) In this section, I examine the semantics of the copy assignment operator and how they are generally modeled. Again, I illustrate the discussion with the help of a Point class: class Point { public: Point ( float x = 0 . 0 , y = 0 . 0 ); / / . . . ( no virtual functions protected: float _x, _y; }; There is no reason to prohibit the copying of one Point object with another in this implementation. So the question is whether the default behavior is sufficient. If all we want to support is the simple assignment of one Point object to another, then the default behavior is both sufficient and efficient and there is no reason to provide an explicit instance of the copy assignment operator. A copy assignment operator is necessary only if the default behavior results in semantics that are either unsafe or incorrect. (For a complete discussion of memberwise copy and its potential pitfalls, see [LIPP91c].) Is the default memberwise copy behavior unsafe or incorrect for our Point objects? No, the coordinates are contained by value, so there are no aliasing or memory leaks that can occur. Moreover, by our providing a copy assignment operator, the program may actually run slower. If we don't provide a copy assignment operator for our Point class and thus rely on the default memberwise copy, does the compiler actually generate an instance? The answer is the same as for a copy constructor: in practice, no. Provided bitwise copy semantics hold for the class, the implicit copy assignment operator is considered trivial and is not synthesized. A class does not exhibit bitwise copy semantics for the default copy assignment operator in the following cases (this is covered in detail in Section 2.2): 1. When the class contains a member object of a class for which a copy assignment operator exists 2. When the class is derived from a base class for which a copy assignment operator exists 3. When the class declares one or more virtual functions (we must not copy the vptr address of the right-hand class object, since it might be a derived class object) 4. When the class inherits from a virtual base class (this is independent of whether a copy operator exists for the base class) The Standard speaks of copy assignment operators' not exhibiting bitwise copy semantics as nontrivial. In practice, only nontrivial instances are synthesized. For our Point class, then, the assignment Point a, b; a = b; is accomplished as a bitwise copy of Point b into Point a; no copy assignment operator is invoked. Semantically and with regard to performance, this is exactly what we want. Note that we still may want to provide a copy constructor in order to turn on the named return value (NRV) optimization. The presence of the copy constructor should not bully us into providing a copy assignment operator if one is not needed. That said, I am now going to introduce a copy assignment operator in order to illustrate the behavior of that operator under inheritance: inline Point& Point::operator=( const Point &p ) { _X = p._X; _Y = p . _ y ; } Now let's derive our Point3d class (note the virtual inheritance): class Point3d : virtual public Point { public: Point3d( float x = -0.0, y = 0 . 0 , float z = 0.0 ) //. . . protected: float _z; }; If we do not define a copy assignment operator for Point3d, the compiler needs to synthesize one based on items 2 and 4 above. The synthesized instance might look as follows: // Pseudo C++ Code: synthesized copy assignment operator inline Point3d& Point3d::operator= ( Point3d *const this, const Point3d &p ) { // invoke the base class instance this->Point::operator=(p); // memberwise copy the derived class members _z = p._z; return *this; }; One of the nonorthogonal aspects of the copy assignment operator with regard to that of the copy constructor is the absence of a member assignment list — that is, a list parallel to that of the member initialization list. Thus we cannot write // Pseudo C++ Code: not supported feature inline Point3d& Point3d::operator= ( const Point3d &p ) : Point ( p3d ), z( p3d._z ) but must write one of two alternative ways of invoking the Base copy assignment operator, either Point :: operator= ( p3d ) ; or ( *(Point*)this ) = p3d; The absence of this copy assignment list may seem a minor point, but without it, the compiler generally cannot suppress the intermediate base class copy operators from being invoked. For example, here is the Vertex copy operator, where Vertex is also virtually derived from Point: // class Vertex : virtual public Point inline Vertex& Vertex::operator=( const Vertex &v) { this->Point::operator=( v ) ; _next = v._next; return *this; } Now let's derive Vertex3d from Point3d and Vertex. Here is the Vertex3d copy assignment operator: inline Vertex3d& Vertex3d::operator=( const Vertex3d &v ) { this->Point::operator=(v); this->Point3d::operator=(v); this->Vertex::operator=(v); } How is the compiler going to suppress the user-programmed instances of the Point copy assignment operator within the Point3d and Vertex copy assignment operators? The compiler can't duplicate the traditional constructor solution of inserting additional arguments. This is because unlike constructors and the destructor, taking the address of the copy assignment operator is legal. Thus this is perfectly legitimate code, for example, although it perfectly confounds attempts to be smart about the copy assignment operator: typedef Point3d& (Point3d::*pmfPoint3d)(const Point3d&) ; pmfPoint3d pmf = &Point3d::operator=; ( x.*pmf) ( x ) ; We can't reasonably support this, however, and still insert an arbitrary number of arguments to the copy assignment operator based on the peculiar characteristics of its inheritance hierarchy. (This has also proved problematic in the support for the allocation of arrays of class objects containing virtual base classes. See Section 6.2 for a discussion.) Alternatively, the compiler might generate split functions for the copy assignment operator to support the class as the most derived and as an intermediate base class. The split function solution is reasonably well de- fined if the copy assignment operator is generated by the compiler; it is not well defined if programmed by the designer of the class. For example, how does one split something like the following, particularly if init_bases() is virtual: inline Vertex3d& Vertex3d::operator=( const Vertex3d &v ) { init_bases( v ); //. . . } Actually, the copy assignment operator is ill behaved under virtual inheritance and needs to be carefully designed and documented. In practice, many compilers don't even try to get the semantics right. They invoke each virtual base instance within each intermediate copy assignment operator, thus causing multiple instances of the virtual base class copy assignment operator to be invoked. Cfront does this as well as the Edison Design Group's front-end, Borland's 4.5 C++ compiler, and Symantec's latest C++ Compiler under Windows. My guess is your compiler does it as well. What does the Standard have to say about this? It is unspecified whether subojects representing virtual base classes are assigned more than once by the implicitly defined copy assignment operator (Section 12.8). A language-based solution would be to provide a "member copy list" extension to the copy assignment operator. Short of this, any solution is program-based and therefore somewhat complicated and error prone. Admittedly, it is a weakness in the language and something one should always examine carefully in code reviews of designs that use virtual base classes. One way to ensure the most-derived class effects the virtual base class subobject copy is to place an explicit call of that operator last in the derived class instance of the copy assignment operator: inline Vertex3d& Vertex3d: :operator= (const Vertex3d &v){ this->Point3d: :operator= ( v ); this->Vertex: : operator= ( v ) } // must place this last if'your compiler does // not suppress intermediate class invocations this->Point::operator=( v ); } This doesn't elide the multiple copies of the subobject, but it does guarantee the correct final semantics. Alternative solutions require factoring out the virtual subobject copying into a separate function and conditionally invoking it depending on the call path. I recommend not permitting the copy operation of a virtual base class whenever possible. An even stronger recommendation: Do not declare data within any class that serves as a virtual base class. 5.4 Object Efficiency In the following set of performance tests, the cost of object construction and copy is measured as the Point3d class declaration increases in complexity as Plain Ol' Data, then as an abstract data type (ADT), and then as single, mul- tiple, and virtual inheritances are incorporated in turn. The following function is used as the primary measure: Point3d lots_of_copies( Point3d a, Point3d b ){ Point3d pC = a; pC = b; // 1 b = a; // 2 return pC; } It contains four memberwise initializations: the two formal arguments, the return value, and the local object pC. It also contains two memberwise copies, those of pC and b on the lines labeled / / 1 and //2 , respectively. The main() function looks as follows: main( Point3d pA( 1.725, 0 .8 7 5, 0. 47 8 ); Point3d pB( 0.315, 0.317, 0.838 ); Point3d pC; for ( int iters = 0; iters < 10000000; iters++ ) pC = lots_of_copies( pA, pB }; return 0; } In the first two programs, the representation is that of a struct and a class with public data: struct Point3d { float x, y, z; }; class Point3d { public: float x, y, z; }; and the initialization of both pA and pB is through the use of an explicit initialization list: Point3d pA = { 1.725, 0.875, 0.478 }; Point3d pB = { 0.315, 0.317, 0.838 }; Both of these representations exhibit bitwise copy semantics, so one expects them to execute equivalent best times for this set of program tests. The results are as follows Memberwise Initialization and Copy: Public Data Members Bitwise Copy Semantics Optimized Non- optimized Cc 5.05 6.39 NCC 5.84 7 .22 The better CC performance is due to an additional six assembler instructions generated in the NCC loop. This "overhead" does not reflect any specific C++ semantics or a poorer h a n d lin g of the code by the NCC front-end—the intermediate C output of both compilers is largely equivalent. It is simply a quirk of the back- end code generator. In the next test, the only change is the encapsulation of the data members and the use of inline access functions and an inline constructor to initialize each object. The class still exhibits bitwise copy semantics, so common sense would tell you that the runtime performance should be the same. Actually, it is slightly off: Memberwise Initialization and Copy: Private Data Members: Inline Access and Inline Construction Bitwise Copy Semantics Optimized Non- optimized Cc 5.18 6.52 NCC 6.00 7.33 I had thought that the difference in performance had to do not with the execution of lots_of_copies() but with the initialization of the class objects within main(). So I modified the struct initialization as follows to du- plicate the inline expansion of the inline class constructor: main() { Po.int3d pA; pA.x = 1.725; pA.y =0.875; pA.z = 0.478; Point3d pB; pB.x = 0.315; pB.y = 0.317; pB.z = 0.838; // . . . rest the same and found that times increased for both executions. They now mirrored those for the encapsulated class representation: Memberwise Initialization and Copy: Public Data Members: Individual Member I n i t ia l iz a t io n Bitwise Copy Semantics Optimized Non- optimized CC 5.18 6.52 NCC 5.99 7.33 The initialization of a coordinate member through the inline expansion of the constructor results in a two- instruction assembler sequence: one to load the constant value within a register and the other to do the actual storage of the value: #20 pt3d pA(1.725, 0.875, 0.478); li.s $ f 4 , 1.7250000238418579e+00 s.s $ f4 , 76($sp) # etc. The initialization of a coordinate member through the explicit initialization list results in a one-expression store because the constant value is "pre-loaded": $$7: . f l o a t 1.7250000238418579e+00 # etc. The other difference between the encapsulated and nonencapsulated Point3d declaration is in the semantics of Point3d pC; Under the ADT representation, pC is automatically initialized with the inline expansion of its default constructor even though, in this instance, it would be safe to leave it uninitialized. On the one hand, although these differences are small indeed, they serve up an interesting caveat to assertions that encapsulation with inline support is the exact equivalent of direct data manipulation common in C programs. On the other hand, these differences generally are not significant and provide no reason for dismissing the software engineering benefits of data encapsulation. They are something to keep in mind for special-case critical code areas. In the next test, I separated the Point3d representation into a concrete three-level single inheritance hierarchy of the form class Point1d {}; // _x class Point2d : public Point1d {}; // _y class Point3d : public Point2d {}; // _z without introducing any virtual functions. Since the Point3d class still exhibits bitwise copy semantics, the addition of single inheritance should not affect the cost of memberwise object initialization or copy. This is borne out by the results: Memberwise Initialization and Copy: Single Inheritance: Protected Members: Inline Access Bitwise Copy Semantics Optimized Non-optimized CC 5.18 6.52 NCC 6.26 7.33 The following multiple inheritance relationship is admittedly contrived. Still, in terms of its member distribution, it does the job, at least in terms of providing us with a test:-). class Pointld { } ; // _x class Point2d {}; // _y class Point3d : public Pointld, public Point2d {}; // _z Since the Point3d class continues to exhibit bitwise copy semantics, the addition of multiple inheritance should not add to the cost of either memberwise object initialization or copy. This proved to be the case except for the optimized CC version, which surprisingly ran slightly better: Memberwise I niti alizati o n and Copy: Multiple Inheritance: Protected Members: Inline Access Bitwise Copy Semantics Optimized Non-optimized CC 5.06 6.52 NCC 6.26 7.33 In all the tests so far, the differences in all these versions interestingly enough revolves around the cost of initializing the three local objects rather than the expense of the memberwise initialization and copy. These operations were carried out uniformly, since all these representations so far support bitwise copy semantics. The introduction of virtual inheritance, however, changes all that. The following one-level virtual inheritance hierarchy: class Pointld { ... } ; class Point2d : public virtual Pointld { class Point3d : public Point2d { . . . }; effectively disallows bitwise copy semantics for the class (the first level of virtual inheritance effectively disallows it; the second level merely compounds it). Synthesized inline instances of the copy constructor and copy assignment operator are generated and are now applied. This result is a significant increase in performance cost: Memberwise Initialization and Copy: Virtual Inheritance: One Level Synthesized Inline Copy Constructor Synthesized Inline Copy Operator Optimized Non- optimized CC 15.59 26.45 NCC 17.29 23.93 To understand this number better, I then stepped back through the previous representations, beginning with the encapsulated class declaration and added a virtual function. Recall that this disallows bitwise copy semantics. Synthesized inline instances of the copy constructor and copy assignment operator are now generated and applied. The performance increase was not nearly as pronounced but still is about 40—50% greater than bit- wise copy support. If the functions were user-supplied non-inline instances, the cost would be still greater: Memberwise Initialization and Copy: Abstract Data Type: Virtual Function Synthesized Inline Copy Constructor Synthesized Inline Copy Operator Optimized Non- optimized CC 8.34 9.94 NCC 7. 6 7 13.05 Following are the times for the other representations with bitwise copy semantics replaced with an inline synthesized memberwise copy construc-' tor and copy assignment operator. These times reflect an increased default cost of object construction and copy as the complexity of the inheritance hierarchy increases. Memberwise Initialization and Copy: Synthesized Inline Copy Constructor Synthesized Inline Copy Operator Optimized Non-optimized Single Inheritance CC 12.69 17.47 NCC 10.35 17.74 Multiple Inheritance CC 14.91 21.51 NCC 12.39 20.39 Virtual Inheritance: Two Levels CC 19.90 29.73 NCC 19.31 26.80 5.5 Semantics of Destruction If a destructor is not defined by a class, the compiler synthesizes one only if the class contains either a member or base class with a destructor. Otherwise, the destructor is considered to be trivial and is therefore neither synthesized nor invoked in practice. Our Point class, for example, by default does not have a destructor synthesized for it, even though it contains a virtual function: class Point { public: Point ( float x = 0 . 0 , float y = 0.0 ); Point ( const Point& ) ; virtual float z ( ); private: float _x, _y; }; Similarly, were we to compose a Line class of two Point objects, class Line { public: Line( const Point&, const Point& ) ; //. . . virtual draw( ) ; // . . . protected: Point _begin, _end;}; Line would not have a destructor synthesized for it because Point is without a destructor. Also, when we derive Point3d from Point—even if the derivation is virtual—if we do not declare a destructor, the compiler in practice, has no need to synthesize one. With both the Point and Point3d classes, a destructor is unnecessary, so providing one is inefficient. You should resist what I call the primal urge toward symmetry: You've defined a constructor, so it just feels right to provide a destructor as well. In practice, you should provide a destructor because it is needed, not because it "feels" right, or, well, because you're not sure if you need one. To determine if a class needs a program level destructor (or constructor, for that matter), consider the case where the lifetime of a class object terminates (or begins). What, if anything, needs to be done to guarantee that object's integrity? This is preferably what you need to program (or else the user of your class has to). This is what should go into the destructor (or constructor). For example, given { Point p t ; Point *p = new Point3d; foo( &pt, p ); delete p; }; we see that both pt and p must be initialized to some coordinate values before being used as arguments to foo(). A constructor is necessary because otherwise the user is required to explicitly provide the coordinate values. Generally, the user cannot examine the state of a local or heap variable to determine whether it has been initialized. It's incorrect to consider the constructors as program overhead because their work otherwise still is required. Without them, use of the abstraction is more error prone. What about when we explicitly delete p? Is any programming necessary? Would you write, prior to applying the delete operator, p - > x ( 0 ); p - > y ( 0 ); No, of course not. There is no reason to reset the coordinate values prior to deleting the object. Nor are there any resources to reclaim. There is no user level programming required prior to the termination of the lifetimes of both pt and p; therefore, there is no need for a destructor. Consider our Vertex class, however. It maintains a list of adjacent vertices, and having the list of adjacent vertices traversed and deleted in turn on the termination of a vertex object (may) makes sense. If this (or some other semantics) is desired, this is the program-level work of the Vertex destructor. When we derive Vertex3d from both Point3d and Vertex, if we don't provide an explicit Vertex3d destructor, then we still require the Vertex destructor to be invoked upon termination of a Vertex3d object. Thus the compiler needs to synthesize a Vertex3d destructor whose only work will be to invoke the Vertex destructor. If we provide a Vertex3d destructor, the compiler augments it to invoke the Vertex destructor after the user- supplied code is executed. A user-defined destructor is augmented in much the same way as are the constructors, except in reverse order: 1. If the object contains a vptr, it is reset to the virtual table associated with the class. 2. The body of the destructor is then executed; that is, the vptr is reset prior to evaluating the user- supplied code. 3. If the class has member class objects with destructors, these are invoked in the reverse order of their declaration. 4. If there are any immediate nonvirtual base classes with destructors, these are invoked in the reverse order of their declaration. 5. If there are any virtual base classes with destructors and this class represents the most-derived class, these are invoked in the reverse order of their original construction. As with constructors, current thinking on the best implementation strategy for the destructor is to maintain two destructor instances: 1. A complete object instance that always sets the vptr(s) and invokes the virtual base class destructors 2. A base class subobject instance that never invokes the virtual base class destructors and sets the vptr(s) only if a virtual function may be invoked from within the body of the destructor An object's lifetime ends with the beginning of its destructor's execution. As each base class destructor is evoked in turn, the derived object in effect becomes a complete object of that type. A PVertex object, for example, becomes in turn a Vertex3d object, a Vertex object, a Point3d object, and then a Point object before its actual storage is reclaimed. Where member functions are invoked within the destructor, this object metamorphosis is ef- fected through the resetting of the vptr within each destructor before user code is executed. The actual semantics of applying destructors within the program are examined in Chapter 6.
Pages to are hidden for
"C5"Please download to view full document


text:
Thanks for redeeming.{{else}}
Success! Thanks for repurchasing.{{/if}} {{else}} {{#if Expired}}
Increase my visibility!{{else}} {{#if IsMultiPack}}
{{#if HasMultiPack}} You have {{MultiPackCount}} top spot(s) left. Now loading you into the search listings... {{else}} You have used all top spots. Now loading you into the search listings... {{/if}}{{else}}
We are loading you into the search listing pages...{{/if}} {{/if}} {{/if}} {{/if}}
{{Current}} just saw you!{{/if}} {{#if LastTopSpotPurchaseIsMulti }} {{#if HasAnyTopSpot}}
{{#if HasFreeTopSpot }} {{ UnclaimedTopSpotFree }} Free {{/if}} {{#if HasPaidTopSpot }} {{#if HasFreeTopSpot }} & {{/if}} {{ MultiPackCount }} {{/if}} Top Spot{{#if Plural}}s{{/if}} Left{{else}}
0 Top Spot{{#if Plural}}s{{/if}} Left{{/if}} {{else}} {{#if HasFreeTopSpot }}
{{ UnclaimedTopSpotFree }} Top Spot{{#if Plural}}s{{/if}} Left{{/if}} {{/if}} {{else}} {{#if HasResults}}
{{Current}} see you now!{{else}} {{/if}} {{/if}}
You can now invite anyone to meet at your favorite Starbucks.
Limited-time feature
51 year old man | San Diego, CA, USA | Seeking women 40-60 within 50 miles
Active within 3 days
Thanks for checking out my profile! The last...
Thanks for checking out my profile! The last few years I've spent pursuing a passion of mine - acting! I've been cast for two guest appearances on soap operas, have done several commercials, a couple of films, and also lead roles in plays. I am not a working actor - it's more of a hobby. Speaking of work, I've spent my most recent time working for two different cities here in San Diego County. Prior to that, ten years or so in supply chain and contracts management, for aircraft and aerospace companies. I grew up on the east coast in a very close knit family. My parents have been married for FIFTY SIX (56) year! My entire family lives back east - I visit them when I can. I feel very lucky not only to have a solid upbringing, but to have parents taught me how to work hard. They raised a son that is strong in character, respective of all people, a good listener, is able to take action, and is comfortable and confident in social settings. I'll get dirty. And I clean up nice too. I have enough common sense to wear latex gloves when working on a project! I enjoy both fine and casual dining. I also like being near the ocean. I could picture myself with you at one of these places...and I REALLY like to stay active, and be outside as much as possible. San Diego has so much to offer, and I love taking in as much as I can. Being on a date with me, you will see the silly, child-like side of me that I feel humbly blessed to have realized. So hopefully you are OK with me kneeling down to pet and hug a dog we come across or to get down to the level of a small child to say hello. I am looking for someone who has a positive, upbeat approach to life, young at heart like myself, and is comfortable with who they are. A person who is active and able to engage in many social environments. My faith in God is strong and I make no apologies for it. Educated, sophisticated women with a high intelligence level is what I seek - these are VERY attractive traits! Thank you again for viewing my profile!
Coffee and conversation , Dining out , Hobbies and crafts , Museums and art , Music and concerts , Exploring new areas , Performing arts , Playing sports
Aerobics, Billiards / Pool, Football, Martial arts, Other types of exercise, Soccer, Swimming, Weights / Machines
I exercise 3-4 times per week.
I like Cats, Dogs, Horses
Anywhere near an ocean!
Penn State University Park, University Park, PA
Kickboxing, bicycle riding, soccer, swimming, weekend trips, etc. With you: Dinner at an upscale restaurant, sunset at the beach, a quick coffee, local events, plays, you name it.
Most of my work days are spent reading technical documents and legal documents. I do read an occasional biography, most recently "ME, Inc." by Gene Simmons. Also "You Can, You Will" by Joel Osteen is terrific.
Z{{Cta}} {{#if HasMoreInfo}} ?{{CtaSecondary}} {{/if}}
|What he is looking for
|5'11" (180cms)
|4'11" (149cms) to 6'0" (182cms)
|Body type:
|Athletic and toned
|Slender, Athletic and toned
|No preference
|Salt and pepper
|No preference
|No Way
|No Way
|Never, Social Drinker
|Executive / Management
|Other profession
My line of work is in contracts and supply chain management.
|I'll tell you later
|No preference
|Never Married
|No preference
|Have kids:
|No preference
|Wants kids:
|Probably not
|Not sure, Probably not, No
|White / Caucasian
|Asian, Latino / Hispanic, Middle Eastern, Native American, Pacific Islander, White / Caucasian, Other
I'm a mixture of British, German, and Dutch. My great (x5) grandfather served in the Revolutionary War, which is how I came up with the User ID for this site.
|Christian / Protestant
|Christian / Catholic, Christian / Protestant, Christian / Other
Prayer and faith in God is a part of me. I don't push my beliefs on others.
|Graduate degree
|Associates degree, Bachelors degree, Graduate degree, PhD / Post Doctoral
I went to school back east, where I earned both of my degrees.

subset: commoncrawl


text:
Welcome! Samaritan Health Services serves the close-knit Oregon communities of the mid-Willamette Valley and central Oregon Coast. Our passion is providing world-class health care to our friends and neighbors. On the job and off, each of us brings the caring and personal commitment to enhance the health of the region we call home.
New center for health education to serve the coastal communities.
Keep your kid healthy this summer by learning to recognize these signs of social or emotional stress.
When do you go to the emergency department, urgent care, make an appointment with your primary care provider or treat the symptoms at home?


text:
Al Gator
Underboss/a.Fam Ent.
Featuring: Marsha Ambrosius
Song: Like This
Absent from the Booth since way back in March of 2011, when he brought us Biggie-inspired mixtape leak Nicky Tarentino, Al Gator returns to our pages with Like This, a freshly-minted cut off his next street album. Here,... More
Posted 3 years ago
Song: Nicky Tarentino
For those who, like yours truly, found themselves wondering, "Who the hell is Nicky Tarentino?!" after reading the title of Al Gator's latest feature, a quick explanation; he's not a real person, but rather an... More
Posted 4 years ago
Al Gator Spits "King Leon" for DJBooth.net Freestyle Series
New York, N.Y. -- Al Gator, the College Park native who earned reader acclaim for mixtape cuts "Hustla Muzik" and "Feelin' It," has stepped into the Booth to bring us the 120th entry in our DJBooth.net Freestyle Series. On... More
Posted 5 years ago
Al Gator & Don Cannon - Chronicles of the Underboss
This classic body of work from Al Gator, the aptly titled Chronicles of the Underboss, is similar to an action packed motion picture, with every genre from thriller to crime to drama to action and yes, even sex, wrapped into... More
Posted 5 years ago
Featuring: Bun B
Song: Hustla Muzik
On single Feelin It, featured back in early September, Al Gator and Aftermath in-house producer Focus showed us yet another creative way to flip a certain Suzanne Vega sample. Now, the Atlanta emcee's looking to repeat... More
Posted 5 years ago
Sample Text - Sample Link


text:
February 1733
March 1733
Lady Mary Wortley Montagu, Verses Address'd to the Imitator of the First Satire of the Second Book of Horace. By a Lady (1733). Pope's couplet on Sappho (ll. 83-4)-
From furious Sappho scarce a milder fate,
P--x'd by her love, or libell'd by her hate.
-was aimed at Lady Mary, with whom Pope had earlier been on intimate terms (see No. 31). By 1728 relations between them were at an end, and Pope (mistakenly) considered that she had a hand in one or two attacks upon him. When Lady Mary persuaded the Earl of Peterborough to ask Pope if she was indeed intended by Sappho, Pope's reply was to claim that the couplet was general satire, and referred with greater aptness to women writers like Mrs Centlivre, Mrs Haywood, Mrs Manley or Aphra Behn. Undeterred, Lady Mary wrote the Verses, with the help of Lord Hervey, and promptly published them. The cuts at Pope are bitter and angry, but they are also shrewd. The poem is perhaps the best written of the many vicious attacks upon Pope's personality and physique. It was published 9 March 1733. There was a reissue, a piracy, and at least two further editions in 1733.
IN two large Columns, on thy motly Page,
Where Roman Wit is striped with English Rage;


text:
Interactive Seating Charts
Unfortunately, we do not currently have
a seating chart for Ocean City Music Pier.
Ocean City Music Pier861 Asbury Avenue
Ocean City, NJ 08226
Upcoming Events
Jul 13
Mon 7:30 PM
Jul 20
Mon 7:30 PM
Jul 27
Mon 7:30 PM
Aug 3
Mon 7:30 PM
Aug 17
Mon 7:30 PM
About Seatgeek
We scour the web's major ticket sites and aggregate inventory into one place. Our Deal Score helps you identify the best ticket deals available for each event.Learn more about SeatGeek


text:
Top Moment #2: Jim Thome's Walk-off
Posted by Amanda Orr, Thu, December 27, 2012 12:20 PM Comments: 4
The Tampa Bay Rays were in town on June 23 for an interleague series with the Phillies. The ending to the game would go down as the arguably the most memorable finish to a Phillies game in 2012.
The Phillies had a comfortable 6-4 lead heading into the top of the ninth inning. With Jonathan Papelbon on the mound, there was plenty of confidence that the Phillies would get the victory easily.
Let's just say, it didn't go as planned.
- Filed under: Posts, Top 10 Moments of 2012


text:
Wednesday, July 1, 2015
The following bills of importance to Georgia's business community take effect today... Full Article
Tuesday, June 30, 2015
On June 29, the Supreme Court of Georgia unanimously upheld a Cobb County trial court's validation of $397 million in revenue bonds which will be used to finance the Atlanta Braves' new stadium.... Full Article
Wednesday, June 17, 2015
Georgia House Districts 24 and 55 held special elections yesterday. With no candidates currently receiving more than 50% of votes, the top two candidates for each race will likely be in a runoff special election on July 14, 2015.... Full Article
Tuesday, June 16, 2015
The Supreme Court of Georgia issued a ruling yesterday that reverses an earlier administrative law judge's (ALJ) ruling that, if allowed to stand, would have imposed a wholly unnecessary, cumulative and cumbersome new level of permitting that would have had a major impact on local economies, job growth, and economic investment in Georgia. ... Full Article
Celebrating the Georgia Chamber's 100th Anniversary at the State Capitol on April 25, 2015.
The Georgia Chamber hosts Regional Power Lunches in partnership with Local Chambers across Georgia this summer.
The annual Eggs & Issues Breakfast served as a kickoff to the 153rd Georgia General Assembly session.


text:
- Food
- Family
- Style
- Series and Features
- Love & Sex
- Work/Life
- Health
- Entertainment
- News
- Blogging
Native American Bloggers You Need to Read
By Grace Hwang Lynch on November 26, 2013
BlogHer Original Post
November is Native American Heritage Month. And there is so much more to indigenous history than a few scenes from a Thanksgiving skit. In fact, there are many Native American women blogging about everything from books, to fashion, to politics, and this month we want to highlight some bloggers we love. I hope you'll check them out!
Native Appropriations PhD student Adrienne K keeps an eye on the portrayals of indigenous people and traditions in pop culture. We especially love her coverage of the Native fashion fails (leopard-print bikini with feathered headdress, anyone?) of Paul Frank and Victoria's Secret in recent months. Thanks to advocates like Adrienne, both Paul Frank Industries and the Limited (parent company of Victoria's Secret) apologized.
Beyond Buckskin When she's not teaching, Dr. Jessica Metcalfe blogs about Native American art, fashion and design. Like Adrienne at Native Appropriations, Jessica also called out Paul Frank on his Pow-Wow party, but what I really love about this site is that it spotlights young Native artists and designers and how they are authentically incorporating their culture into their work.
American Indians in Children's Literature Want to read a book that accurately portrays the experiences of Native Americans? Dr. Debbie Reese is a professor of education who writes this extensive blog which reviews books, for adults as well as kids, about the American Indian experience and also writes many helpful reading guides for all levels of literature.
Goodfox Julia Goodfox blogs about culture and politics when she is not teaching or doing interviews about Native American politics, and race relations and human rights in general. She also keeps tabs on the art and culture of her local community in Lawrence, Kansas.
When Turtles Fly I first found this website while helping my son research his fourth grade project about the California Missions, and wanted to find out what Native Americans thought about this standard part of elementary school curriculum. It turns out, Deborah A. Miranda has a whole section about the California Missions project on her blog, and often answers inquiries from school kids, too. A must-read for any Golden State parent who wants to raise culturally-aware kids.
Happy Native American History Month!
News and Politics Editor Grace Hwang Lynch blogs at HapaMama and A Year (Almost) Without Shopping.
Related Posts
More Like This
Recent Posts by Grace Hwang Lynch
Most Popular on BlogHer
By Lori Luna
Follow BlogHer
Love Your Summer with Sparkling ICE
Sparkling ICE is a bold flavored sparkling water that truly delivers on taste and contains just the right amount of fizz. Read our bloggers' posts and get more details on how you can enter the Flavor Face Off plus find out more about the delicious flavors that Sparkling ICE has to offer. Read more
Most Popular on Race & Class
ADDED: New Thursday Afternoon Kick-Off Keynote at #BlogHer15 Featuring #womenslives and #BlackLivesMatter
Recent Comments on Race & Class
When You Look at Me You Don't See Color – Your Loss!
By Shellireads
Please Keep Talking About Charleston
My Fourth of July is no celebration
ADDED: New Thursday Afternoon Kick-Off Keynote at #BlogHer15 Featuring #womenslives and #BlackLivesMatter
ADDED: New Thursday Afternoon Kick-Off Keynote at #BlogHer15 Featuring #womenslives and #BlackLivesMatter


text:
Information on "Energy" and "South Asia"
February 2015
19 Feb 2015
Some Issues in Respect of India's Nuclear Liability Law - II
Author: G Balachandran
Publisher: Institute for Defence Studies and Analyses (IDSA)
This brief looks at India's nuclear liability law, focusing on whether India's Civil Liability for Nuclear Damage Act (CLNDA) conforms to the international Convention on Supplementary Compensation (CSC). More on «Some Issues in Respect of India's Nuclear Liability Law - II»
January 2015
Jan 2015
Building Synergies: The Northeast & India's New Government
Author: Wasbir Hussain, Arunav Goswami, Rani Pathak Das
Publisher: Institute of Peace and Conflict Studies (IPCS)
This brief sets out a series of recommendations for the Indian government on how it can address the development problems which are evident in the northeast of the country. More on «Building Synergies: The Northeast & India's New Government»
Jan 2015
Governing Uranium in India
Author: Rajiv Nayan
Publisher: Danish Institute for International Studies (DIIS)
This report analyzes 1) the Indian nuclear industry's demand for natural uranium; 2) its sources of supply and the state of uranium production in India; and 3) the legal framework that regulates the use of nuclear material in the country. More on «Governing Uranium in India»
December 2014
8 Dec 2014
Resolving India's Nuclear Liability Impasse
Author: Vinod Kumar, Kapil Patil
Publisher: Institute for Defence Studies and Analyses (IDSA)
This brief discusses India's Civil Liability for Nuclear Damage Act (CLNDA), which establishes a liability framework that makes all major participants in a nuclear power project accountable for its safe functioning. More on «Resolving India's Nuclear Liability Impasse»
3 Dec 2014
New 'Oil Shock' – Impact on South Asia
Author: Shahid Javed Burki
Publisher: Institute of South Asian Studies (ISAS)
This brief looks at the consequences of OPEC's November 2014 decision not to cut the output of its oil production in South Asia. More on «New 'Oil Shock' – Impact on South Asia»
Dec 2014
How to Use Climate Finance
Author: Mark Daniel Jaeger, Axel Michaelowa, Katharina Michaelowa
Publisher: Center for Security Studies (CSS)
According to this paper, a new grand bargain on global climate change mitigation will depend on the success of the UNFCCC's $100 billion Green Climate Fund. More on «How to Use Climate Finance»
September 2014
25 Sep 2014
A New Defining Moment in India-China Dialogue
Author: P S Suryanarayana
Publisher: Institute of South Asian Studies (ISAS)
This paper describes the strategic, economic and diplomatic significance of the Sino-Indian Joint Statement issued on 19 September 2014 following talks between India's Prime Minister Narendra Modi and Chinese President Xi Jinping. More on «A New Defining Moment in India-China Dialogue»
August 2014
Aug 2014
Military and Strategic Affairs, Vol 6, No 2
Author: Avi Beker, Liran Antebi, Alex Altshuler, Meir Elran, Elai Rettig, Shlomi Yass, Gabi Siboni, Sami Kronenfeld
Publisher: Institute for National Security Studies (INSS)
The articles in this issue deal with 1) UN peacekeeping and its limitations; 2) the implications of increased proliferation of unmanned aerial vehicles among non-military actors; 3) the professionalization of Israel's emergency management system; 4) ... More on «Military and Strategic Affairs, Vol 6, No 2»
March 2014
25 Mar 2014
Governance in India: Infrastructure
Author: Beina Xu
Publisher: Council on Foreign Relations (CFR)
This paper looks at the economic infrastructure problems faced by India as burgeoning trade puts pressure on India's inefficient ports and rapid urbanization strains the country's unreliable electricity and water networks. More on «Governance in India: Infrastructure»
Mar 2014
Global Nuclear Materials Security: Perspectives from India
Author: Lalit Mansingh, R Rajaraman, Sheel Kant Sharma, P R Chari
Publisher: Institute of Peace and Conflict Studies (IPCS)
In the run-up to the 2014 Nuclear Security Summit (NSS) in The Hague, this discussion report reviews and critiques elements of the global stewardship of nuclear materials' security and considers India's role in these efforts. More on «Global Nuclear Materials Security: Perspectives from India»


text:
Ruby Jewel creates extraordinarily delicious ice cream for all to enjoy. Every flavor is carefully hand-crafted daily in our North Portland kitchen using the best ingredients thoughtfully sourced from farmers and food artisans in Oregon and around the Northwest. Family owned and operated since 2004, we are committed to supporting our local community, economy, and limiting our impact on the environment wherever possible.
Always Flavors
Caramel with Salted Dark Chocolate
Oregon Strawberry
Cookies & Cream
Double Chocolate
Singing Dog Vanilla Bean
Fresh Mint with Chocolate Flake
Mississippi Specials
Peanut Butter Dream
Brown Sugar Sour Cream
Malted Milk Chocolate w/Cookies
Caramel Bacon Brittle
Banana Cream Pie
Raspberry Truffle
Honey Lavender
Strawberry Basil
Raspberry Lemonade
West End Specials
Peanut Butter Dream
Honey Lavender
Brown Sugar Sour Cream
Caramel Bacon Brittle
Raspberry Truffle
Milk Chocolate Malt w/ Double Chocolate Coooie
Strawberry Basil
Raspberry Lemonade


text:
Tel: (423)989-4346
School Overview
|School Membership(s)School Assoc.
|American Association of Christian Schools (AACS)
|Religious Affiliation
|Grades Offered
|Grades Kindergarten - 5
Student Body
|Total Students
|84 students
|Student Body Type
|% Students of Color
State avg.: 18%
|Students by Grade
Academics and Faculty
|Total Classroom Teachers
|5 teachers
|Student : Teacher Ratio
National avg.: 13:1
|Average Class Size
|12 students
Nearby Schools:
All Schools | High Schools | Elementary Schools | Preschools | Public Schools
Show me:
- School Location Miles Students Grades
BristolMountain Empire Baptist School
1317 Weaver Pike
Bristol, TN 37620
(423)968-7116(Baptist)0.7 mi | 64 students | Gr. PK-12
BristolBrookside Academy
109 Crestwood Rd
Bristol, TN 37620
(423)878-6681(Baptist)0.9 mi | 13 students | Gr. PK-10
BristolSt Annes School
300 Euclid Ave
Bristol, VA 24201
(276)669-0048(Roman Catholic)1.5 mi | 165 students | Gr. PK-8
BristolTri-Cities Christian School
2031 Broad Street
Bristol, TN 37620
(423)968-3574(Christian)1.7 mi | 151 students | Gr. NS-6
BristolVictory Children's Center
11123 Island Rd
Bristol, VA 24202
(276)669-3008Daycare / Preschool (Baptist)3 mi | 53 students | Gr. PK-KG
School Reviews
Area Statistics
Rental Market Monitor
Recent Articles
Updated June 28, 2015
When it comes to choosing a private school, there are so many choices to consider that the project can be a huge challenge to most of us. We offer some help and advice to help you get started.
Sending your child to a foreign language school makes good sense when you have been posted to this country from abroad and in other circumstances as well.
Do you need financial aid? Not sure? Confused by how financial aid works? Here are some answers.


text:
Browse these popular wedding categories:
Sort by: Show per page
- 2 items
Sort by: Show per page
- 2 items
Related Products
Personalized Floating Unity Candle Set
Torn between being traditional or modern on your wedding day? Be both with this personalized floating unity candle set. Gorgeous ...
Glittering Beads Unity Candle Stand Set
Add some glitter and glam to your traditional wedding ceremony with this unity candle stand set. Candle holders are nickel ...


text:
Users Online Now:
Who's On?
Visitors Today:
Pageviews Today:
Threads Today:
Posts Today:
Join Our:
GLP Poker Rooms
Check Out:
GiveMeGossip.com - Gossip Forum
Donate To GLP
Adv. Search
Back to Forum
Back to Thread
Message Subject
North Korea is a illuminati pawn, most of you are too stupid to see that and have gone full retard in a doomtard frenzy................
Poster Handle
Anonymous Coward
Post Content
they armed north korea u doomtard sheep
they met secretly with north korean elite in march you doomtard sheep
kim jong ill was a fucking actor before he became a 'evil dictator' you retarded doomtard sheep
junior kim jong got his training at a fucking illuminati training school in switzerland u dummy doomtard sheep
all the mind control movies in theatres made and planned years ago have north korea as the bad guy (olympus falling, red dawn, gi joe) you doom tard sheep
Anonymous Coward 37748131
EXACTLY! 5 stars OP
The US government gave NK the nukes. Bill Clinton gave NK two fissionable nuclear reactors. When they threatened to make nuke bombs, George Bush gifted them with 4 more for a total of 6 fissionable nuclear reactors.
The NK "threat" is all a carefully orchestrated psyop to keep the sheeple in fear and to distract them from the real threat...the collapse of the US financial system. All world leaders are friends and belong to the same Zionist Jesuit controlled club.
Most of the nuclear devices are already INSIDE the USSA.
They were smuggled in parts and secretly put together in targeted cities awaiting detonation commands from the Jesuit controllers of the military industrial espionage complex and the Israeli Mossad. The sheeple have no idea.
Anonymous Coward 19138044
Please verify you're human:
Reason for copyright violation:
What Goes Into A SlimJim?
Blue eyed-people at higher risk for alcohol dependency
Destroying America 101: The Blueprint Exists
Government Trolls Are Using 'Psychology-Based Influence Techniques' On YouTube, Facebook And Twitter
Doomsday Preppers Are Getting Ready For An Imminent Collapse
Deal Reached: Wireless Remote Drug-Releasing Microchip Implants On The Assembly Line
Facebook Can Now Identify You in Pictures Even Without Your Face Showing
Milk producers are dumping out hundreds of thousands of gallons of milk, right into fertilizer pits in order to drive prices back up.
Brain study sheds light on how new memories are formed
"The Fallout Ratio" Is Flashing Red - The Chart That Realtors Don't Want You To See
Solar Impulse attempts to cross weather front
We may be heading toward a new food economy that's more competitive and innovative.
Jade Helm The Hard Core Truth Finally Explained!
This Online Anonymity Box Puts You a Mile Away From Your IP Address
600 Dogs Mysteriously Jump From 'Haunted' Bridge In Scotland
Russia to ban Coca-Cola and Pepsi
DARPA: We Are Engineering the Organisms That Will Terraform Mars
Uber Faces Another Privacy Complaint - Tracking Users After Leaving Car?
Baltimore Police Called Out For Making Up 'Gang Violence' Stories To Scare Public
DHS/Police say criminals drive cars that's why they're using a new infrared license plate scanning system
Obama Issues 19 Classified Directives Changing Laws Passed by Congress
How Activists Won Reparations for the Survivors of Chicago Police Department Torture
Teacher Fired After He Stepped On U.S. Flag In Class
Kindergarten Application Form Asks If Child Was Born By C-Section
Weird Crop Patterns Appear In England (Video)
This Flag Represents The Principle, "Fight For What You Believe In."
This Is The Rebel Flag, "You're Either Free Or You're Not."
Disclaimer / Copyright Info
Privacy Policy
Terms Of Use
with questions or comments about this site.
"Godlike Productions" & "GLP" are registered trademarks of Zero Point Ltd. Godlike™
Website Design Copyright © 1999 - 2015 Godlikeproductions.com
Page generated in 0.007s (3 queries)


text:
The seventh incarnation of a German-Jewish poet
Mascha Kaleko, a beloved German poet of the 1930s, eventually reached Israel, where she slipped into anonymity. But with republished volumes of her work, she finds a new voice and a new generation of fans - in Germany.
Text size
Mascha Kaleko interpreted her life as a series of incarnations. Six of them, to be exact.
The full text is available for subscribers & registered users.
Click here to register for free, to subscribe ($1 for the first 4 weeks) or login
Like us on Facebook and get articles directly in your news feed


text:
Cross-country from Santa Clara, Donahue, Schneider & more impress in local competitions
While most of the eyes of swimming fandom were locked on Santa Clara this weekend for the finale of the Arena Pro Swim Series, a number of high-profile athletes chose to stay closer to home for various local meets.
Josh Schneider: I'm trying to push my way to the top (Video Interview)
Josh Schnieder held off a talented field to win the men's 50 freestyle with his time of 21.96.
2015 Arena Pro Swim Charlotte: Day 3 Finals Race Videos
Watch all of the A finals from day 3 of the 2015 Arena Pro Swim Series meet in Charlotte, North Carolina.
2015 Arena Pro Swim Charlotte: Day 3 Finals Live Recap
Follow along for live updates from Day 3 finals of the 2015 Arena Pro Swim Series at Charlotte.
More cool photos from Charlotte Pro Swim Series
Day 3 is a wrap and the fun and fast swimming continue. There's a definite buzz in the air as…
2015 Arena Pro Swim Series Charlotte: Day 3 Prelims Live Recap
With the comeback in full force, Michael Phelps swam his first 200m fly since the 2012 London Olympics. He wasn't afraid to attack the race early on, leading the way to the 100 meter wall in 57.09. At the 150, Phelps was still in front, but that last 50 seemed to prove to be trouble.
FINA's List of Swimmers with Rio Qualifying Times Updated As of May 1, 2015
FINA released an updated listing of the 2016 Rio Olympic "A" cut qualifiers through May 1st; take a look to find your favorite swimmer.
2015 TYR JAX 50 Sprint Dual Challenge: Watch Live
Professional swimmers including Arianna Vanderpoole-Wallace, Madison Kennedy, Hannah Riordan, Katarina Filova, Josh schneider, Felipe Lima, Mark Weber, and Elvis Burrows will all be racing.
2015 Arena Pro Swim Series Mesa: Day 3 Race Videos
Watch all of the finalsa races from Friday in Mesa, including Arkady Vyatchanin's win in the 100 back, plus the 200 flys, 50 frees, 200 breasts, and 400 frees.
50 champ Josh Schneider transitions training to focus on 100
While Josh Schneider might be a coach, he's not done as a swimmer, and won the A-final by .01 in a time of 22.52
2015 Arena Pro Swim Series Mesa: Day 3 Finals Live Recap
Tyler Clary is the top seed in the men's 200 butterfly after winning the 400 IM last night.
Race Video: Bruno Fratus wins 50 Freestyle, Arena Pro Swim Series Orlando 2015
Race Video courtesy of Universal Sport's Network, a SwimSwam partner.
Team TYR Photo Shoot- Behind The Scenes – Photo Vault
This past January the athletes of TYR Sport met up in California for a fun-in-the-sun photo shoot. Go behind the scenes here…
TYR Sport re-signs five-time Short Course World medalist Josh Schneider
Press release: TYR Sport is proud to announce the re-signing of 5x World Championship medalist Josh Schneider to its roster.
True or False – Swimmers Don't Do Land Sports
When swimmers take to the field, court or track it can be difficult for their bodies to adjust to activities such as running, but is it really because of swimming?


text:
I'm looking for a way to do periodic bluetooth inquiry's from my Android Smartphone (HTC Desire with Android 4.0.1). The Device is rooted and it is a custom Rom installed so that I have full privileges. I already wrote a shellscript, which uses hcitool, hciconfig and hcidump to do the inquiry's. That works fine so far, but it is a little to slow for me. I guess that's because of my dirty workaround of using an android-app to execute a shellscript from linux. Although I got problems by killing the executed processes via my App.
So I'd like to find a way to inquire BT Devices from the Android API. I found out that there is no possibility 'til now to do this, but i read about the bluez API which is possibly able to fit my requests. Does anyone have any links, tips or advises for me?
I haven't found anything useful :/
Thanks in advance.
Edit (2012-09-28):
Okay, I think I'm a little closer to the solution now. I downloaded the source of blueZ library from: bluez.org Then i put the important files (hci.h, bluetooth.h, hcilib.h and their sourcefiles) into the jni folder of my android project and compiled them into my shared library. I wrote a JNI Wrapper around the function
hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap,inquiry_info **ii, long flags)
and followed the advises of this book to do my inquiry. Everything fine 'til here.
But when I start the inquiry, the function
dev_id = hci_get_route(NULL);
always returns -1, and I can't continue.
Bluetooth is activated, and i already tried to grant root access to my application. Not better :(
Anything I did wrong until here? Isn't it allowed to use BlueZ HCI commands from a android app? I mean JBlueZ doesn't do anything else is it?
My native code looks like this:
inquiry_info *ii = NULL;
int max_rsp, num_rsp;
int dev_id, sock, len, flags;
int i;
char addr[19] = { 0 };
char name[248] = { 0 };
dev_id = hci_get_route(NULL);
if (dev_id < 0 ) {
LOGI("ERROR ON finding Device ID");
sock = hci_open_dev( dev_id );
if (sock < 0) {
LOGI("ERROR ON opening socket");
len = 8;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;
ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));
num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
LOGI("INQUIRY Executed!!!");
(*env)->CallVoidMethod(env, obj, callBackID, num_rsp);
Thank you for any help.


text:
Working at university on the borderline between mathematics and computer sciences.
- Germany
- martin.von-gagern.net
- Member for 2 years, 11 months
- 0 profile views
- Last seen May 3 '14 at 20:51
Communities (33)
Top Network Posts
- 84More options when flagging for migration
- 71Add "Flag as Other" checkbox to "Vote to Close as Off-Topic" dialog
- 45How to hide a password passed as command line argument?
- 43Is Git crowdsourcing cryptographic attacks?
- 42Fastest way to meet, without communication, on a sphere?
- 36How does intuition fail for higher dimensions?
- 36Exact difference between CharSequence and String in java
- View more network posts →
Keeping a low profile.
This user hasn't posted... yet.
Badges (3)
Gold —
Silver 2
Bronze 1


text:
Join FREE | Login
& Deals
& Celebrations
©2014 General Mills, Inc. All Rights Reserved. This information will only be used to send an email to your friend(s) and will not be saved. Please read our Privacy Policy.
No-Roll Mexican Rice Enchiladas
Progresso® broth and beans provide a wonderful addition to this nacho pot pie made using Old El Paso® seasoning mix and Green Giant® Niblets® corn – a wonderful Mexican-style dinner.
Crushed tortilla chips make a creative crunchy topping for this kid-friendly chicken casserole.
© 2015 ®/TM General Mills All Rights Reserved


text:
There is no proof the settlers did this, and even if there were it wouldn't stand up to scrutiny. And even if it did that at least some of those settlers responsible may be mentally challenged and deserve a court trial to determine their mental status. And don't forget those people who go to mosques are the same ones who are members of organized terrorist groups that murder Israelis. And they send suicide bombers into our country. And they use their own children as weapons. And they deserve everything they get. And if you don't agree with me you are a numbnut. Take it from one who is.
If selected for publication, it will appear as soon as possible on Haaretz.com.