Derived class issues with arrays and casting in C++

I’m working my way through C++ FAQs book by Cline and Lomow, and it’s excellent. There’s lots of issues going on with inheritance, arrays and casting that could be a real pain to deal with towards the end of system development, but that you can nip in the bud and make life easier for yourself. For example, just knowing that an array of objects of a Derived class is NOT a kind-of array of objects of the Base class can prevent you a lot of headaches…

// Book: C++ FAQs by Cline & Lomow
// FAQ 136 & 137 - Is array-of Derived a kind-of array-of Base?
// Answer: NO!
 
#include <iostream>
using namespace std;
 
class Base
{
	protected:
		int i;
 
	public:
		Base() : i(42*42)      { }
		virtual ~Base()        { }
		virtual void service() { cout << "Base::service() called.\n" << flush; }
};
 
class Derived : public Base
{
	protected:
		// Add some extra things so that an object of type Derived is a different
		// size to an object of type Base
		int j;
		float k;
		unsigned long l;
 
	public:
		Derived() : Base(), j(42*42*42) { }
		virtual void service()          { cout << "Derived::service() called.\n" << flush; }
};
 
// Userland function
void useSubscript(Base *b)
{
	cout << "b[0].service(): " << flush; b[0].service();
	cout << "b[1].service(): " << flush; b[1].service(); // BOOM! Segfault!
 
	// This fails because the size of Base and the size of Derived are different:
	// "The fundamental problem is that a pointer to the first of an array-of-things
	// has exactly the same type as a pointer to a single thing. This was inherited
	// from C."
	//
	// In essence, as we're passing in Base pointers, in this case Base moves from
	// element to element in 16 byte intervals, but we actually provided an array
	// of Derived objects, which have a size of 32 bytes each, so b[1] starts
	// at b[0]+16, which is really only half-way through our first Derived element d[0]!
	//
	// The way to do this properly is to use a templatised container class instead.
	// If you tried to pass Array<Derived> as Array<Base> this would be caught at compile time.
}
 
int main()
{
    Derived d[10];
 
    cout << "Base has a size of   : " << sizeof(Base)    << " bytes." << endl;         // 16 bytes
    cout << "Derived has a size of: " << sizeof(Derived) << " bytes." << endl << endl; // 32 bytes
 
    useSubscript(d);
 
    return 0;
}

Good to know – now I just have to keep it in mind when I’m coding!

How-To: Initialise arrays of objects in Java

You might think, like I did, that if you create an array of objects in Java then the constructor is automatically called on each object as part of the array creation process. But you’d be wrong.

Creating an array merely creates the object references – you have to instantiate each “inner” object in the array as a separate step if you want to be able to, ya know, do stuff… I think this is because in Java an array is an object – like, quite literally a single object that can be passed around like a single thing.

An example, perhaps?

Person Class

public class Person
{
	private int number = -1; // Each person gets a default number of -1 on creation
 
	// Default constructor
	public Person()
	{
		// The number property is left as -1 as per the default value specified above
	}
 
	// One parameter constructor which overwrites the default number value with a specified value
	public Person(int theNumber)
	{
		number = theNumber;
	}
 
	public void displayNumber()
	{
		System.out.println("My person number is: " + number);
	}
}

PersonTestDrive Class

public class PersonTestDrive
{
	final static public int MAX_PEOPLE = 3;
 
	public static void main(String[] args)
	{
		// Create an array of people. You're not creating any new People objects here - you're creating a new Array object
		Person[] people = new Person[MAX_PEOPLE];
 
		// *** INCORRECT : The Person objects in the people array don't exist yet! They're only references at this point! ***
		// for (Person tempPerson : people)
		// {
		// 	tempPerson.displayNumber(); // This doesn't give "-1" for each person, it gives a NullPointerException!
		// }
 
		// *** CORRECT : Instantiate each Person object in the array before accessing them! ***
		for (int loop = 0; loop < MAX_PEOPLE; loop++)
		{
			people[loop] = new Person(loop+1); // Create the Person object, setting the number property in this case
 
			people[loop].displayNumber();      // Now it'll output "My person number is: 1" etc. as expected
		}
	}
}

An introduction to ActionScript 3.0 – week 4 lesson 1

I stopped organising the slides for web publication after week 3 lesson 2 (back in March 2010!) because I just wasn’t seeing any demand, and if no-one’s using them, there was no point in me working on ’em. Apparently at least one person has found the slides useful and asked about any further sets, so I’m happy to put ’em together if they’ll be used.

ActionScript Slides Week 4 Lesson 1

As you might have worked out from the title slide above, we’re covering variables, constants, arrays and loops and some push/pop stuff – all good, solid first steps to getting fun stuff done w/ AS3 =D

Download slides link: An Introduction to ActionScript 3.0 – Week 4, Lesson 1
Audience: Beginners who know a little about variables and how to perform some basic programming math.
Format: Powerpoint 2003 (so they can be opened in LibreOffice/OpenOffice, MS Office 2K3/2K7/2K10 etc.)
Template: OOo2 by Chih-Hao Tsai
Content License: These slides are released under a creative commons non-commercial attribution share-alike 3.0 license by me (r3dux), which means that you are encouraged to copy, distribute and modify the work, but must attribute the original author. Further, you may not use the work for commercial purposes, and any derivative works must be released under the same license. These slides come with no guarantee of correctness, fitness for purpose or anything of the sort. They are correct to the best of my knowledge, nothing more – nothing less. The work and any comments therein contain my own personal opinions and not those of my employer or anyone related to education in Australia in any way, shape or form. Issues, comments? Put something in the contact form in the top right or leave a comment on this article. Cheers!