#include using namespace std; class Thing { private: // data member declarations int size; int a, b, c; // a few more members (not used) static int count; // a class member public: // member function prototypes Thing() // default constructor { size = Thing::count++; } Thing(int x) // another constructor { size = x; } int getSize() { return size; } int print() { return size; } void setSize(int size) { this->size = size; } }; // allocate memory and initialize static class member int Thing::count = 63; int main(int argc, char* argv[]) { cout << "sizeof(Thing) = " << sizeof(Thing) << endl; // testing 4 ways to create an array of objects // *** static array of objects *** // In this case the array may not be modified. It is a constant and // it will always refer to the same 10 memory locations, and each memory // location contains a Thing object. Thing thingArray[10]; // thingArray refers to thingArray[0] // sizeof(thingArray) = 10 * sizeof(Thing) // thingArray[0] is an object of type Thing // sizeof(thingArray[0]) = sizeof(Thing) cout << "\nstatic array:\n-------------\n"; cout << "Thing thingArray[10];\n"; cout << " thingArray = " << thingArray << " sizeof(thingArray) = " << sizeof(thingArray) << endl; cout << " thingArray[0] = " << thingArray[0].print() << " sizeof(thingArray[0]) = " << sizeof(thingArray[0]) << endl; cout << " thingArray[9] = " << thingArray[9].print() << " sizeof(thingArray[9]) = " << sizeof(thingArray[9]) << endl; // *** dynamic array of objects *** // In this case the array may be modified. It may be set to any address // value that is a pointer to an array of Thing objects (or to NULL) and // will refer to the memory locations starting at whatever address it is // assigned. However, each array element must be a Thing object. Thing *thingArrayPtr; thingArrayPtr = new Thing[10]; // Create a new, unnamed static array and assign // pointer to the static array. // thingArrayPtr points to element [0] of the // unnamed Thing array // thingArrayPtr refers to memory that begins an array of Thing objects // sizeof(thingArrayPtr) = 4 (the size of a pointer variable) // *thingArrayPtr is same as thingArrayPtr[0] and refers to memory // that begins a Thing object // sizeof(*thingArrayPtr) = sizeof(Thing) // sizeof(thingArrayPtr[0]) = sizeof(Thing) // *(thingArrayPtr+i) is same as thingArrayPtr[i] cout << "\ndynamic array:\n--------------\n"; cout << "Thing *thingArrayPtr;\nthingArrayPtr = new Thing[10];\n"; cout << " thingArrayPtr = " << thingArrayPtr << " sizeof(thingArrayPtr) = " << sizeof(thingArrayPtr) << endl; cout << " *thingArrayPtr = " << (*thingArrayPtr).print() << " sizeof(*thingArrayPtr) = " << sizeof(*thingArrayPtr) << endl; cout << " thingArrayPtr[0] = " << thingArrayPtr[0].print() << " sizeof(thingArrayPtr[0]) = " << sizeof(thingArrayPtr[0]) << endl; cout << " thingArrayPtr[9] = " << thingArrayPtr[9].print() << " sizeof(thingArrayPtr[9]) = " << sizeof(thingArrayPtr[9]) << endl; cout << " *(thingArrayPtr+9) = " << (*(thingArrayPtr+9)).print() << " sizeof(*(thingArrayPtr+9)) = " << sizeof(*(thingArrayPtr+9)) << endl; cout << "\nthingArrayPtr = &thingArray[0];\n"; thingArrayPtr = &thingArray[0]; // Can also assign pointer to the address of any // other array of Thing objects. // thingArrayPtr points to thingArray[0]; cout << " thingArrayPtr = " << thingArrayPtr << " sizeof(thingArrayPtr) = " << sizeof(thingArrayPtr) << endl; cout << " *thingArrayPtr = " << (*thingArrayPtr).print() << " sizeof(*thingArrayPtr) = " << sizeof(*thingArrayPtr) << endl; cout << " thingArrayPtr[0] = " << thingArrayPtr[0].print() << " sizeof(thingArrayPtr[0]) = " << sizeof(thingArrayPtr[0]) << endl; cout << " thingArrayPtr[9] = " << thingArrayPtr[9].print() << " sizeof(thingArrayPtr[9]) = " << sizeof(thingArrayPtr[9]) << endl; cout << " *(thingArrayPtr+9) = " << (*(thingArrayPtr+9)).print() << " sizeof(*(thingArrayPtr+9)) = " << sizeof(*(thingArrayPtr+9)) << endl; cout << " (thingArrayPtr+9)->print() = " << (thingArrayPtr+9)->print() << endl; thingArrayPtr = &thingArrayPtr[9]; cout << "thingArrayPtr = &thingArrayPtr[9];\n" << " // DANGER! thingArrayPtr now points to a Thing object,\n" << " // not to an array of Thing objects.\n" << " // (or you could say it now points to an array of length 1)." << endl; cout << " thingArrayPtr = " << thingArrayPtr << " sizeof(thingArrayPtr) = " << sizeof(thingArrayPtr) << endl; cout << " *thingArrayPtr = " << (*thingArrayPtr).print() << " sizeof(*thingArrayPtr) = " << sizeof(*thingArrayPtr) << endl; cout << " // Now accessing thingArrayPtr[i] for i != 0\n" << " // might cause a memory error (or, it might not)." << endl; // *** static array of pointers to objects *** // In this case the array may not be modified. It is a constant and // it will always refer to the same 10 memory locations. But, each memory // location contains a pointer to a Thing object and that pointer may be // set to any address value that is a pointer to a Thing object (or to NULL). Thing* thingPtrArray[10]; for ( int i = 0; i < 10; i++ ) thingPtrArray[i] = new Thing(); // create a new Thing object and make ith // array element point to it // thingPtrArray refers to thingPtrArray[0] // sizeof(thingPtrArray) = 10 * 4 (10 pointer variables) // thingPtrArray[0] is ptr to an object of type Thing (initial value = NULL) // sizeof(thingPtrArray[0]) = 4 (size of a pointer variable) // *thingPtrArray[0] is an object of type Thing (if thingPtrArray[0] != NULL) // sizeof(*thingPtrArray[0]) = sizeof(Thing) cout << "\nstatic array of pointers to objects:\n------------------------------------\n"; cout << "Thing* thingPtrArray[10];\n"; cout << "for ( int i = 0; i < 10; i++ )\n thingPtrArray[i] = new Thing();\n"; cout << " thingPtrArray = " << thingPtrArray << " sizeof(thingPtrArray) = " << sizeof(thingPtrArray) << endl; cout << " *thingPtrArray = " << *thingPtrArray << " sizeof(*thingPtrArray) = " << sizeof(*thingPtrArray) << endl; cout << " thingPtrArray[0] = " << thingPtrArray[0] << " sizeof(thingPtrArray[0]) = " << sizeof(thingPtrArray[0]) << endl; cout << " *thingPtrArray[0] = " << (*thingPtrArray[0]).print() << " sizeof(*thingPtrArray[0]) = " << sizeof(*thingPtrArray[0]) << endl; cout << " thingPtrArray[9] = " << thingPtrArray[9] << " sizeof(thingPtrArray[9]) = " << sizeof(thingPtrArray[9]) << endl; cout << " *thingPtrArray[9] = " << (*thingPtrArray[9]).print() << " sizeof(*thingPtrArray[9]) = " << sizeof(*thingPtrArray[9]) << endl; // *** dynamic array of pointers to objects *** // In this case the array may be modified. It may be set to any address // value that is a pointer to an array of pointers to Thing objects (or to NULL) // and will refer to the memory locations starting at whatever address it is // assigned. In addition, each array element in the array is a pointer to a // Thing object. So, the elements of the array may point to any Thing object, // and the array elements can be modified to point to different Thing objects // at different times during execution. For example, 2 or more array elements // could point to the same Thing object. Thing **thingPtrArrayPtr; thingPtrArrayPtr = &thingArrayPtr; // assign the "address of" a static array of // pointers to Thing objects // thingPtrArrayPtr refers to memory that begins an array of pointers to Thing objects // sizeof(thingPtrArrayPtr) = 4 (the size of a pointer variable) // thingPtrArrayPtr[0] is a pointer a to Thing object // *thingPtrArrayPtr is a pointer a to Thing object // sizeof(thingPtrArrayPtr[0]) = 4 (the size of a pointer variable) // thingPtrArrayPtr[0] is the same as *thingPtrArrayPtr // *thingPtrArrayPtr[0] is a Thing object // sizeof(*thingPtrArrayPtr[0]) = sizeof(Thing) cout << "\ndynamic array of pointers to objects:\n-------------------------------------\n"; cout << "Thing **thingPtrArrayPtr;\n"; cout << "thingPtrArrayPtr = &thingArrayPtr;\n"; cout << " thingPtrArrayPtr = " << thingPtrArrayPtr << " sizeof(thingPtrArrayPtr) = " << sizeof(thingPtrArrayPtr) << endl; cout << " *thingPtrArrayPtr = " << *thingPtrArrayPtr << " sizeof(*thingPtrArrayPtr) = " << sizeof(*thingPtrArrayPtr) << endl; cout << " thingPtrArrayPtr[0] = " << thingPtrArrayPtr[0] << " sizeof(thingPtrArrayPtr[0]) = " << sizeof(thingPtrArrayPtr[0]) << endl; cout << " *thingPtrArrayPtr[0] = " << (*thingPtrArrayPtr)[0].print() << " sizeof(*thingPtrArrayPtr[0]) = " << sizeof(*thingPtrArrayPtr[0]) << endl; cout << " thingPtrArrayPtr[9] = " << thingPtrArrayPtr[9] << " sizeof(thingPtrArrayPtr[9]) = " << sizeof(thingPtrArrayPtr[9]) << endl; cout << " *thingPtrArrayPtr[9] = " << (*thingPtrArrayPtr)[9].print() << " sizeof(*thingPtrArrayPtr[9]) = " << sizeof(*thingPtrArrayPtr[9]) << endl; cout << " **thingPtrArrayPtr = " << (**thingPtrArrayPtr).print() << " sizeof(**thingPtrArrayPtr) = " << sizeof(**thingPtrArrayPtr) << endl; cout << " *(*thingPtrArrayPtr+1) = " << (*(*thingPtrArrayPtr+1)).print() << " sizeof(*(*thingPtrArrayPtr+1)) = " << sizeof(*(*thingPtrArrayPtr+1)) << endl; cout << " (*thingPtrArrayPtr+1)->print() = " << (*thingPtrArrayPtr+1)->print() << endl; }