• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 421
  • Last Modified:

Declaring CArray HELP!

I have a class CBase and classes CDerived1 and CDerived2 which are both  derived from CBase as Public.

I am trying to declare CArray to contain pointers to the base class CBase.  The pointers will either point to CDerived1 or CDerived2.  From the CArray I want to return CBase pointer then call virtual functions to execute methods of either CDerived1 or CDerived2, depending which one the pointer was pointing to. My declaration looks like this:

CArray<CBase, CBase*) BaseArray;

This seems to fail as:
c:\program files\microsoft visual studio\vc98\mfc\include\afxtempl.h(443) : error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'class CBase *' (or there is no acceptable conversion)
        c:\program files\microsoft visual studio\vc98\mfc\include\afxtempl.h(1566) : while compiling class-template member function 'void __thiscall CArray<class CBase,class CBase *>::SetAtGrow(int,class CBase *)'
Error executing cl.exe.

What am I doing wrong?  How can I declare correctly and also please show me how to declare the derived classes, point CBase pointer to the derived class object and put the base pointer in the array

Thanks



0
gbzhhu
Asked:
gbzhhu
1 Solution
 
balugaaCommented:
it is not difficult to see why your declaration is producing an error:
 
CArray<CBase, CBase*> BaseArray is saying declare an array of objects from pointers to that object.

If you want to store pointers use
typedef CArray<CBase*, CBase*> BaseArray.

if you want to store objects use
typedef CArray<CBase, CBase&> BaseArray.

Hope this helps
0
 
ZoppoCommented:
or simply use a CTypedPtrArray like this:

CTypedPtrArray <CPtrArray, CBase*> BaseArray;

ZOPPO
0
 
mikeblasCommented:
Add an operator=() to your class which accepts a CBase* as a right-hand operator.

-- begin arr.cpp --

#include <afxtempl.h>

class CBase
{
public:
   CBase() { }
   ~CBase() { }

   operator=(const CBase* pBase) { }
};

void main()
{
   CArray<CBase, CBase*> baseArray;

   CBase baser;
   baseArray.SetAtGrow(35, &baser);
}

-- end file arr.cpp --

..B ekiM


0
Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

 
gbzhhuAuthor Commented:
For mikeblas

Your answer compiles but the pointer of CBase returned from the array will not invoke virtual methods of the derived classes CDerived1 and CDerived2, therefore no use for me.

For ZOPPO

Again your comment is fine except that CPtrArray class is not serializable and I need to serialize objects.

For Balugaa.

I think your suggestion of storing pointers is my choice and should work for me except:

I managed to add to the array pointers of CBase pointing to derived classes, however, as soon as I call one of the virtual methods, the program crashes and I get unhanled exception error and then the Disassembly window appears which shows memory addresses (that is not really my cup of tea!! I can't understand it)

Any idea why it isn't working.

If any of you don't understand what I am trying to do then please let me know I will explain properly.
 
0
 
mikeblasCommented:
gbzhhu> Your answer compiles but the pointer of CBase returned from the array will
 gbzhhu> not invoke virtual methods of the derived classes CDerived1 and CDerived2, therefore
 gbzhhy> no use for me.

Huh?  What pointer? The way you've declared the array, an object is being returned. How are you getting a pointer?

Since you're returning an object, you're going to have a hard time finding polymorphism.

 gbzhhu> except that CPtrArray class is not serializable and I
 gbzhhu> need to serialize objects.

Implementing Serialize() for this case is trivial. Do you need help with it?

..B ekiM
0
 
gbzhhuAuthor Commented:
OK mikeblas,

You know your stuff - I don't.  I will explain what I am trying to achieve so that you can help me.

I created the base class just to use inheritance(part of the requirement)  it is actually called CBug class and I have a CGreenBug and CRedBug classes.  I would like to create an array of CBug pointers  then create bug as I need it (green or red) then use a CBug pointer to point to the bug I created and then put the CBug pointer in the array.  At a latter stage, I want to retrieve array element, say i and assign that to a CBug pointer, then call the CBug pointer's virtual functions, so that depending whether it is red or green bug the appropriate function gets called.  On top of this I would like to serialize object to disk, and read them again.

If you could help me with this I would greatful and would increase points by 50.

Thanks for your help.

PS: Please remember, I am quite new to this, actual code (like you did previously) would help rather than explanation in words.
0
 
mikeblasCommented:

Well, there's several ways to skin a cat.  This code will do exactly what you have asked, but you'll need to manually clean-up the content of the array when you're done.

There's a couple of ways around that. But, this is what you asked for.

-- begin arr2.cpp --

#include <afxtempl.h>

class CBase
{
public:
   CBase() { }
   ~CBase() { }

   virtual Foo() { printf("CBase::Foo()\n"); }
};

class CDerived1 : public CBase
{
public:
   CDerived1() { }
   ~CDerived1() { }

   virtual Foo() { printf("CD::CDerived1()\n"); }
};

class CDerived2 : public CBase
{
public:
   CDerived2() { }
   ~CDerived2() { }

   virtual Foo() { printf("CD::CDerived2()\n"); }
};

void main()
{
   CArray<CBase*, CBase*> baseArray;

   // add some items
   CDerived1* pDer1 = new CDerived1;
   CDerived2* pDer2 = new CDerived2;
   CBase* pBase = new CBase;

   baseArray.SetAtGrow(0, pDer1);
   baseArray.SetAtGrow(1, pDer2);
   baseArray.SetAtGrow(2, pBase);

   // access a virtual member of each

   int n;
   for (n = 0; n <= baseArray.GetUpperBound(); n++)
   {
      printf("%d: ", n);
      CBase* pElement = baseArray.GetAt(n);
      pElement->Foo();
   }

   // remember to clean-up the array!

   for (n = 0; n <= baseArray.GetUpperBound(); n++)
      delete baseArray.GetAt(n);
   baseArray.RemoveAll();

   return;
}

-- end file arr2.cpp --

..B ekiM
0
 
gbzhhuAuthor Commented:
Adjusted points to 150
0
 
gbzhhuAuthor Commented:
mikeblas,

Thanks,
I have given you an A grade for your brilliant answer and raised points to 150 as  promised.

I am assuming that this method you suggested will support serialization. Please could confirm that it does so as I am not sure.

Thanks again top dog!!
0
 
mikeblasCommented:
Yes, CArray supports serialization.

..B ekiM
0

Featured Post

Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now