Base class pointer vector confusion

I've gotten myself conceptually stuck in trying to convert a working C++ program from a C-style approach to one using inheritance and polymorphism. In particular, the problem revolves around using base class pointer vectors to contain pointers to particular derived class objects. A given base class pointer vector will only contain pointers to one specific derived class, but there is one such vector for each derived class.

The previous implementation looked like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct L{
	int row, col;
	// () and (int, int) constructors
 };

 struct B{
	L where;
	int** matrixA;
	// (), (int, int) (const L&) constructors which also initialize matrixA to NULL
	// and a function to compare an external L obj with where
};

enum bType {Type1, Type2, ..., TypeN};
vector<L> tempL1, tempL2, ..., tempLN; // these are filled at start of turn elsewhere in prog
vector<B> B1, B2, ..., BN; // these are matched with tempLx vectors and Typex bType
			// and are used as persistent storage of the values in the tempL vectors 

and within the function that calculates a single player-move

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fillUpTempLs(); // based on parsing of piped stdin game codes

if(turn==1)
{
	create(B1, tempL1, Type1);
	...
	create(BN, tempLN, TypeN);
}
else
{
	reconcile(B1, tempL1, Type1);
	...
	reconcile(BN, tempLN, TypeN);
}
// rest of move func. 

The functions create and reconcile work as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
create(vector<B>& BB, vector<L>& LL, const bType bT)
{
	// for each entry in LL, create element in BB
	// based on bT, alloc or don't memory for matrix1
	// if using matrix1, call fcn to prepare for filling it
	// when ready, fill matrix1 according to bT
	// then "publish" values in matrix1 to a larger game map overlay
	
	LL.clear();
};
reconcile(vector<B>& BB, vector<L>& LL, const bType bT)
{
	// step through BB
	// step through LL looking for BB[i], if found erase LL[j] and go to next BB
	// if not found, either do nothing or mark BB[i] for destruction
	// end loop
	// remove all entries in BB marked for destruction after unpublishing matrix1 values and
	// delete[] matrix1 in steps
	
	create(BB,LL,bT); // add the remaining LL elements into BB
};

This is what I was using, and it worked fine until I discovered that I wanted B3 to have an extra variable, and realized other "types" might also require different structures.

So I now have:
1
2
3
4
5
6
7
8
9
10
11
class A
{
int row, col;
//constructors
}
class B:public A
{
int** matrix1;
//constructors
}
class D1:public B {/*constructors*/} // also classes D2,..., DN 

and I'm changing B1,...,BN to vector<B*>'s, so create and reconcile arg list is now (vector<B*>&,vector<L>&) hopefully without using bType at all.

Now I understand how to use a base class pointer vector to hold the values of "new D1(...)", and how I can use pure virtual fcns in B with over-ridden implementations in D1, D2, etc. but I'm totally stuck on one particular issue.

I want to rewrite the functions create and reconcile so that I use the pure virtual methods in B to remove the switch/case parts, and keep only the generic code (or move some of that too into B), but I can't for the life of me figure out how to actually call "new DerivedClass" within create without naming the actual class Di, which means I can't do without the enum const in the arg list. I could move that part perhaps to my main makeMove() fcn, but that defeats the purpose of hiding it all away in create and reconcile (which actually calls create itself).

Am I missing something here? I don't see implementing what I want in either B or the Di's, but perhaps I'm wrong about that -- I mean, B is not supposed to be aware of the Di classes, and Di can't call "new Di" within its own methods, can it?

Any help would be greatly appreciated. Thanks.

EDIT: I'm not sure if I was mistaken here: "Di can't call "new Di" within its own methods". In the Marshall Cline C++ FAQ I found a discussion of "virtual constructors": http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8 Is that what I'm looking for? And clearly I can call "new Di" within Di, and return a pointer to Di, so maybe that's the way to go?
Last edited on
Topic archived. No new replies allowed.