Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Non-Compliant Code Example

Code Block
bgColor#FFCCCC
langcpp
class Base {
public:
	virtual void func(void) {
		cout << "Base" << endl;
	}
};

class Derived : public Base {
public:
	int i;
	Derived() { i = 0; }

	void func(void) {
		cout << "Derived " << ++i << endl;
	}
};

void walk(class Base *bar, int count) {
	for (int i = 0; i < count; i++) {
		bar[i].func();
	}
}

int main(void) {
	Base dis[3];
	Derived dat[3];

	walk(dis, 3);
	walk(dat, 3); // crashes
}

...

Instead of having an array of objects, an array of pointers solves the problem of the objects being of different sizes. With the Base and Derived classes as in the Non-Compliant Code Example, we can define the walk and main methods as follows.

Code Block
bgColor#ccccff
langcpp
void walk(class Base *bar [], int count) {
	for (int i = 0; i < count; i++) {
		(bar[i])->func();
	}
}

int main(void) {
	Base* dis[3] = {new Base, new Base, new Base};
	Base* dat[3] = {new Derived, new Derived, new Derived};

	walk(dis, 3);
	walk(dat, 3);

  for (int i = 0; i < 3; i++) {
    delete dis[i];
    delete dat[i];
  }
}

...

A better approach would be to use vectors and iterators, instead of arrays, as follows. (Note, however, that we have to have vectors of pointers because containers must be homogeneous.)

Code Block
bgColor#ccccff
langcpp
void walk(vector<Base*>bar) {
	for_each (bar.begin(), bar.end(), mem_fun(&Base::func));
}

int main(void) {
	vector<Base*> dis(3);
        for (int i=0; i<3; i++) dis[i] = new Base;

	vector<Base*> dat(3);
        for (int i=0; i<3; i++) dat[i] = new Derived;

	walk(dis);
	walk(dat);

  for (int i = 0; i < 3; i++) {
    delete dis[i];
    delete dat[i];
  }
}

...