?
Solved

Declaring CArray HELP!

Posted on 2000-03-10
10
Medium Priority
?
417 Views
Last Modified: 2013-11-20
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
Comment
Question by:gbzhhu
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
10 Comments
 

Expert Comment

by:balugaa
ID: 2604241
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
 
LVL 31

Expert Comment

by:Zoppo
ID: 2604257
or simply use a CTypedPtrArray like this:

CTypedPtrArray <CPtrArray, CBase*> BaseArray;

ZOPPO
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2605259
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
Will your db performance match your db growth?

In Percona’s white paper “Performance at Scale: Keeping Your Database on Its Toes,” we take a high-level approach to what you need to think about when planning for database scalability.

 
LVL 12

Author Comment

by:gbzhhu
ID: 2609770
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
 
LVL 11

Expert Comment

by:mikeblas
ID: 2609912
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
 
LVL 12

Author Comment

by:gbzhhu
ID: 2610598
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
 
LVL 11

Accepted Solution

by:
mikeblas earned 600 total points
ID: 2610879

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
 
LVL 12

Author Comment

by:gbzhhu
ID: 2614024
Adjusted points to 150
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 2614025
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
 
LVL 11

Expert Comment

by:mikeblas
ID: 2614087
Yes, CArray supports serialization.

..B ekiM
0

Featured Post

Get MongoDB database support online, now!

At Percona’s web store you can order your MongoDB database support needs in minutes. No hassles, no fuss, just pick and click. Pay online with a credit card. Handle your MongoDB database support now!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Suggested Courses

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question