?
Solved

problem with CreateThread (syntax?)

Posted on 2005-03-15
62
Medium Priority
?
2,053 Views
Last Modified: 2007-11-27
This code:

   // Start the acquisition thread
    m_hCameraThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CameraThread, (LPDWORD*)this, 0, &dwThreadId);

is giving me this error:
error C2440: 'type cast' : cannot convert from '' to 'unsigned long (__stdcall *)(void *)'

I'm not sure how to fix this?

thanks
-Paul
0
Comment
Question by:PMH4514
[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
  • 26
  • 22
  • 8
  • +1
62 Comments
 
LVL 30

Expert Comment

by:Axter
ID: 13546779
Hi PMH4514,
Which argument are you getting the error on?
Can you give us the complete error message, and what are the types for the arguments you're passing in?

David Maisonave :-)
Cheers!
0
 
LVL 86

Accepted Solution

by:
jkr earned 1200 total points
ID: 13546870
'CameraThread' needs to be declared as

DWORD WINAPI CameraThread(
  LPVOID lpParameter   // thread data
);
 
and if it is a member function of any class, be sure to make it 'static'.

0
 

Author Comment

by:PMH4514
ID: 13547458
the complete error is:
error C2440: 'type cast' : cannot convert from '' to 'unsigned long (__stdcall *)(void *)'
        None of the functions with this name in scope match the target type

it's defined in Camera.h:

protected:
    static HANDLE m_hCameraThread;

and the eror is when I try to compile a derived class. The error occurs regardless if m_hCameraThread is static or not.  It must have something to do with the fact that I'm trying to use it in a derived class?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Expert Comment

by:jkr
ID: 13547541
>>The error occurs regardless if m_hCameraThread is static or not

No, I meant that the thread *function* - if a member function - needs to be static. How is 'CameraThread()' declared?
0
 
LVL 30

Expert Comment

by:Axter
ID: 13547576
FYI:
If CameraThread is the right type, then you wouldn't need the LPTHREAD_START_ROUTINE cast.

Can you remove the LPTHREAD_START_ROUTINE, and  compile it.
You'll probably get a more informmed error.

Also please post the declaration for CameraThread.
0
 

Author Comment

by:PMH4514
ID: 13547578
ahh.. yup, that was it..

was like:
      virtual DWORD CameraThread(LPDWORD lpdwParam);            // thread method

now like
      static DWORD CameraThread(LPDWORD lpdwParam);            // thread method

and it compiles.

can I still implement CameraThread in the derived class w/o having defined it as virtual?
0
 
LVL 30

Expert Comment

by:Axter
ID: 13547594
>>can I still implement CameraThread in the derived class w/o having defined it as virtual?

Yes, but it's not going to work from a base type pointer or reference.
0
 
LVL 86

Expert Comment

by:jkr
ID: 13547601
>>can I still implement CameraThread in the derived class w/o having defined it as virtual?

You can implement one, sure. 'virtual' does not really make sense for static members, though.
0
 
LVL 30

Expert Comment

by:Axter
ID: 13547616
In other words

Base *b = new Derived();

b->CameraThread(); //This will call the base class CameraThread function, and not the Derived::CameraThread

And if you're base class tries to pass CameraThread as an argument, it will be the base class function, and not the derived CameraThread function.
0
 
LVL 30

Expert Comment

by:Axter
ID: 13547640
If you have derived functionallity that you want CameraThread to perform, I recommend you have CameraThread call your virtual function.

You can do this if you pass a pointer to the derived class when you create the thread.
0
 

Author Comment

by:PMH4514
ID: 13547705
hmm..  but a thread control method has to be static right?

basically, I have my CCamera which is a base class:

class CCamera  
{
public:
      CCamera();
      virtual ~CCamera();

      virtual DWORD StartCapture();                                    // starts capture
      static DWORD CameraThread(LPDWORD lpdwParam);            // thread method
// etc.

}

Camera.cpp does this:
DWORD CameraThread(LPDWORD lpdwParam)
{
    // Base class has no functionality
    ASSERT(FALSE);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

I have two derived CCamera types, each needs to implement the thread function its own way.

in each, on my "StartCapture" method I do:

    m_hCameraThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CameraThread, (LPDWORD*)this, 0, &dwThreadId);

as well, in their respective implementations I do:

    m_hCameraThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CameraThread, (LPDWORD*)this, 0, &dwThreadId);

DWORD CameraThread(LPDWORD lpdwParam)
{
 //..
}

0
 
LVL 86

Expert Comment

by:jkr
ID: 13547724
>>but a thread control method has to be static right?

Yes, but you can circumvent that using

DWORD SomeClass::CameraThread(LPDWORD lpdwParam)
{
   SomeClass* p = (SomeClass*) lpdwParam;

    return p->DerivedClassThreadImplementationNonStatic ();
}
0
 

Author Comment

by:PMH4514
ID: 13547769
so if it is static, does it have to be implemented in the base class (even if that implementation is as you just described where it forwards the call into the derived class?)
0
 
LVL 30

Expert Comment

by:Axter
ID: 13547771
To add to above comment, make sure it's a virtual function.
Example:

class CCamera  
{
public:
     CCamera();
     virtual ~CCamera();

     virtual DWORD StartCapture();                              // starts capture
     static DWORD CameraThread(LPDWORD lpdwParam);          // thread method
     virtual DWORD CameraThread();  //Virtual function to allow derive class to have it's own methods
// etc.

}

DWORD SomeClass::CameraThread(LPDWORD lpdwParam)
{
   CCamera  * p = (CCamera  *) lpdwParam; //This really should be cast to base class type CCamera  

    return p->CameraThread(); //Now you'll get derived method via virtual function CameraThread (no parameters)
}
0
 

Author Comment

by:PMH4514
ID: 13547795
so my derived CameraThread, as it stands where it takes the paramater from which I can cast the class type, I can re-write it as if it were a standard class method, with direct access to its members?
0
 
LVL 86

Expert Comment

by:jkr
ID: 13547806
>> so if it is static, does it have to be implemented in the base class

It does not have to, but that's where I'd put it.
0
 
LVL 30

Expert Comment

by:Axter
ID: 13547807
>>so if it is static, does it have to be implemented in the base class (even if that implementation is as you just
>>described where it forwards the call into the derived class?)

I recommend that you do place the static fucntion in the base class.
You can then make your virtual function protected.

Using the method I posted above, you can just have one static CameraThread function.
And then your derived class can override the virtual CameraThread function to get specific functionallity for that class.
0
 

Author Comment

by:PMH4514
ID: 13547830
ok, so now I have the static CameraThread(LPDWORD lpdwParam) implemented in the base class, as Axter illustrated, where it propogates the call into the derived class CameraThread() method..

But, within my derived class, how do I create the thread? This line no longer works again

    m_hCameraThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CameraThread, (LPDWORD*)this, 0, &dwThreadId);

with the same error as in the original post.
0
 
LVL 30

Expert Comment

by:Axter
ID: 13547851
Can you post the base class with new modifications, and the derived class?
0
 

Author Comment

by:PMH4514
ID: 13547859
header or .h and .cpp?
0
 
LVL 30

Expert Comment

by:Axter
ID: 13547865
Also, I recommend you removed the (LPTHREAD_START_ROUTINE) cast.

When you post the class, please include complete delcaration so we can also see the data member types.
0
 
LVL 86

Expert Comment

by:jkr
ID: 13547873
>>where it propogates the call into the derived class CameraThread()

Try to give that a different name...
0
 
LVL 30

Expert Comment

by:Axter
ID: 13547877
>>header or .h and .cpp?

complete header, and just the function(s) that calls CreateThread.
0
 

Author Comment

by:PMH4514
ID: 13547880
here is the header for the base class:

#if !defined(AFX_CAMERA_H__DD0CED48_7873_483D_97E0_87459F8691B8__INCLUDED_)
#define AFX_CAMERA_H__DD0CED48_7873_483D_97E0_87459F8691B8__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


class CCamera  
{
public:
      CCamera();
      virtual ~CCamera();

      virtual DWORD StartCapture();                                    // starts capture
      virtual DWORD StopCapture();                                    // stops capture
      virtual DWORD PauseCapture();                                    // pauses capture, stores local buffer of last frame
      virtual DWORD ResumeCapture();                                    // resumes capture
      virtual DWORD Reset(BOOL a_bInitHardware = FALSE);      // resets camera
      virtual DWORD Initialize();                                          // initializes camera.
      virtual DWORD GrabImage(auto_ref_ptr<CFramePacket> pPacket);      // populates pPacket->Buffer with image data.
      virtual DWORD StartRecord();
      virtual DWORD StopRecord();
      virtual DWORD PauseRecord();
      virtual DWORD CaptureFrame();                                    // informs CPacketFilter to capture next packet.
      static DWORD CameraThread(LPDWORD lpdwParam);            // thread method
      virtual DWORD CameraThread();                                    // to allow derived classes their own implementations
protected:
      BYTE* m_pPauseBuffer;                                                // copy of last frame before pause.
                                                                                    // is pushed to GrabFrame(BYTE* pBuffer) if capture paused.
    HANDLE m_hCameraThread;
      CConfigManager* m_pConfigManager;      
};

#endif // !defined(AFX_CAMERA_H__DD0CED48_7873_483D_97E0_87459F8691B8__INCLUDED_)


-------------------------------

and the header for the derived class:

class CCameraImaq : public CCamera  
{
public:
      CCameraImaq();
      virtual ~CCameraImaq();
    DWORD SetAcquisitionWindow();

      DWORD StartCapture();                                    // starts capture
      DWORD StopCapture();                                    // stops capture
      DWORD PauseCapture();                                    // pauses capture, stores local buffer of last frame
      DWORD StartRecord();                                    // starts video capture
      DWORD StopRecord();                                          // stops video capture
      DWORD PauseRecord();                                    // pauses video capture
      DWORD CaptureFrame();                                    // informs CPacketFilter to capture next packet.
      DWORD Reset(BOOL a_bInitHardware = FALSE);      // resets camera
      DWORD Initialize();                                          // initializes camera.
      DWORD GrabImage(auto_ref_ptr<CFramePacket> pPacket);      // populates pPacket->Buffer with image data.
      DWORD CameraThread();                                    


private:
    SESSION_ID   m_SessionID;
    INTERFACE_ID m_InterfaceID;

    long        m_AcqWinWidth;
    long        m_AcqWinHeight;
    long        m_CanvasWidth;            // 640(512) width of the display area
    long        m_CanvasHeight;            // 512(384) height of the display area
    long        m_CanvasTop;            // top of the display area
    long        m_CanvasLeft;            // left of the display area

      int m_iSnapDelay;

      DWORD InitializeCard();
};


and then I won't post the implementation of the derived class, it's long, the line in question is:

   m_hCameraThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CameraThread, (LPDWORD*)this, 0, &dwThreadId);


0
 

Author Comment

by:PMH4514
ID: 13547901
(complete method for create thread)

DWORD CCameraImaq::StartCapture()
{
    DWORD dwThreadId;

    // Start the acquisition thread
    m_hCameraThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CameraThread, (LPDWORD*)this, 0, &dwThreadId);

    if (m_hCameraThread == NULL)
        return GetLastError();

         return ERROR_SUCCESS;
}
0
 
LVL 30

Expert Comment

by:Axter
ID: 13547917
>>and then I won't post the implementation of the derived class, it's long, the line in question is:
>>   m_hCameraThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CameraThread, (LPDWORD*)this,
>>0, &dwThreadId);

Try the following:
m_hCameraThread = CreateThread(NULL, 0, CCamera::CameraThread, (LPDWORD*)this, 0, &dwThreadId);

Put the CCamera:: prefix on the static function argument, and remove the casting.
0
 

Author Comment

by:PMH4514
ID: 13547932
nope:

error C2664: 'CreateThread' : cannot convert parameter 3 from 'unsigned long (void)' to 'unsigned long (__stdcall *)(void *)'
        None of the functions with this name in scope match the target type


(I'll be gone now for a few hours.. carry on :)

0
 
LVL 30

Expert Comment

by:Axter
ID: 13547987
This should fix above error:
Change your static declaration to the following:

static DWORD WINAPI CameraThread(LPVOID  lpdwParam);          // thread method
0
 

Author Comment

by:PMH4514
ID: 13549011
yes Axter that fixed that..

I must have skrewed something, up now I'm getting a bunch of errors like this:

CameraImaq.obj : error LNK2005: "unsigned long __cdecl CameraThread(unsigned long *)" (?CameraThread@@YAKPAK@Z) already defined in Camera.obj
CameraMacro.obj : error LNK2005: "unsigned long __cdecl CameraThread(unsigned long *)" (?CameraThread@@YAKPAK@Z) already defined in Camera.obj
Camera.obj : error LNK2001: unresolved external symbol "public: virtual unsigned long __thiscall CCamera::CameraThread(void)" (?CameraThread@CCamera@@UAEKXZ)
CameraMacro.obj : error LNK2001: unresolved external symbol "public: virtual unsigned long __thiscall CCamera::CameraThread(void)" (?CameraThread@CCamera@@UAEKXZ)
Camera.obj : error LNK2001: unresolved external symbol "public: virtual unsigned long __thiscall CCamera::PauseRecord(void)" (?PauseRecord@CCamera@@UAEKXZ)

those symbols are all defined in their respective classes
0
 

Author Comment

by:PMH4514
ID: 13549083
oh.. duh, disregard that last post
0
 

Author Comment

by:PMH4514
ID: 13549112
axter: I missed this comment from you ealier:

>If CameraThread is the right type, then you wouldn't need the LPTHREAD_START_ROUTINE cast.

could you please ellaborate?

thanks
0
 
LVL 30

Assisted Solution

by:Axter
Axter earned 400 total points
ID: 13549181
>>could you please ellaborate?

Without the cast, the compiler can more accurately compare the types, to determine if you have the right argument type.

If the CameraThread function is of the right type, then you don't need to cast it.

You should avoid casting as much possible, and you should only cast when you're absolutely sure that it's right.
When you cast, you're telling the compiler that you know what you're doing, and to ignore what the compiler thinks is a potential error.

There are times when you really do need to cast:
Example:

DWORD SomeClass::CameraThread(LPDWORD lpdwParam)
{
   CCamera  * p = (CCamera  *) lpdwParam; //This is a good place for casting

The above line is a good reason for casting, although most C++ programmers would recommend that a C++ cast be used instead of a C-Cast.
0
 

Author Comment

by:PMH4514
ID: 13549253
ok I see.

I am still having a compile problem with regard to the CreateThread

again, my base class defines:

      static DWORD WINAPI CameraThread(LPVOID  lpdwParam);          // thread method
      virtual DWORD CameraThread();                                    // to allow derived classes their own implementations


my derived class implements:

DWORD CCameraImaq::CameraThread()
{
 //
}

my derived class trys to create the thread:
      m_hCameraThread = CreateThread(NULL, 0, CCamera::CameraThread, (LPDWORD*)this, 0, &dwThreadId);
and I get:

CameraImaq.obj : error LNK2001: unresolved external symbol "public: static unsigned long __stdcall CCamera::CameraThread(void *)" (?CameraThread@CCamera@@SGKPAX@Z)
Debug/vivascope.exe : fatal error LNK1120: 1 unresolved externals

if I comment that line out (CreateThread) it compiles fine.
0
 

Author Comment

by:PMH4514
ID: 13549266
>>although most C++ programmers would recommend that a C++ cast be used instead of a C-Cast.

what's the difference? (syntactically and otherwise)
0
 
LVL 30

Expert Comment

by:Axter
ID: 13549324
The error you just posted is referring to the static function, and not the virtual function.

Please post the implementation for your static CameraThread.

Should be modified to match your class declaration.

DWORD WINAPI CCamera::CameraThread(LPVOID lpdwParam)
{
   CCamera  * p = (CCamera  *) lpdwParam; //This really should be cast to base class type CCamera  

    return p->CameraThread(); //Now you'll get derived method via virtual function CameraThread (no parameters)
}

0
 
LVL 30

Expert Comment

by:Axter
ID: 13549364
>>what's the difference? (syntactically and otherwise)

C++ has four different cast.
dynamic_cast
static_cast
const_cast
reinterpret_cast

It's suppose to be safer to use these cast because it narrows the type of cast you can do, and it suppose to tell anyone who's reading your code more information as to why you're casting.
I don't noramlly use these cast myself, since I'm not a fan of them, so I wouldn't be a good expert to give you much more details on their usage.
0
 

Author Comment

by:PMH4514
ID: 13549384
oh yeah, duh, forgot to change the interface to match the WINAPI declaration, now it works

thanks
-Paul
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 13555875
>> so if it is static, does it have to be implemented in the base class    

>> static DWORD WINAPI CameraThread(LPVOID  lpdwParam);          // thread method
>> virtual DWORD CameraThread();      // to allow derived classes their own implementations

Instead of using virtual function it would have been much simpler using static functions of the derived classes. It seems to me that the recommendation to put the thread start function to the baseclass, given both by jkr and Axter,  was based on a misunderstanding. If you have two classes each of them needs an own implementation of  it's own thread, you easily could use the static member defined in the derived class.

Regards, Alex
0
 

Author Comment

by:PMH4514
ID: 13555951
>>It seems to me that the recommendation to put the thread start function to the baseclass, given both by jkr and Axter,  was based on a misunderstanding.

what misunderstanding was that? (just to clarify for me the differences)

Basically my system is connected physically to 2 different types of camera hardware. Only one will be capturing and presenting data to the screen at a given time (for now at least, there's talk of dual monitors, but that's off a ways). I've defined the base class CCamera so that they each implement the same interface, but each needs its own implementation of the thread, of course, because physical hardware differences require different code to interface with the hardware. From an interface standpoint, I want all "cameras" to be the same so that the rest of my system doesn't care where the image data came from.

If putting the thread start function in the base class was a misunderstood suggestion, could you describe the scenario in which doing so is appropriate?

thanks!
-Paul
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 13556283
>>>> what misunderstanding was that?

I suppose there was a misunderstanding because you defined the initial thread start function as virtual.

But virtual functions only make sense if you are using baseclass pointers of different derived classes. If you already have a derived object, e. g. the this pointer of a member function of the derived class, or a pointer to the derived class, there is no need to use virtuality.

However, you should know that static member functions don't have a 'this' object but are some kind of global functions - that's the reason you can pass them via function pointer to a thread. So, the suggestion of jkr to pass the this pointer as an argument to the thread, make a cast to the pointer in the thread start function and call a non-static member function, is very recommendable independent of any virtuality issue.

Regards, Alex
0
 

Author Comment

by:PMH4514
ID: 13556309
interesting.. I guess I thought if you had the interface for a method defined in a base class that you intended to override in a derived class (wouldn't you always?) that you had to declare it as virtual.
0
 
LVL 30

Expert Comment

by:Axter
ID: 13556427
>>interesting.. I guess I thought if you had the interface for a method defined in a base class that you intended to
>>override in a derived class (wouldn't you always?) that you had to declare it as virtual.

If it's possible that your base class, or any upper level class is going to create the thread with a derived class object, then you do want to use a virtual class.

It it's possible that you want to allow a sub class or over ride the thread logic, then you want to use a virtual class.

IMHO, it's safer to just use the virtual class by default, so that you don't run into problem later if the code gets changed.

It also makes more sense to me to just create one static function.
Otherwise you would have to create a static function for each derived class.

From an OO point of view, I think it makes much more sense to use the static function / virtual function combination.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 13556502
Indeed,  "overriding" a baseclass function makes only sense if the baseclass function as defined as virtual.

*But*, the virtuality only comes to play if you call the virtual function using a baseclass pointer of a derived object.

 class A
 {
 public:
       virtual void f();      
 };

 class B : public A
 {
 public:
       virtual void f() { cout << "B::f" << endl; }      
 };

 class C : public A
 {
 public:
       virtual void f() { cout << "C::f" << endl; }      
       void g()          { f(); }
 };


  ...
  C c;
  c.f();   // calls C::f

  B* pB = new B;
  pB->f();  // calls B::f

  c.g();   // call C::f

  A* pA = &c;
  pA->f();    // calls C::f

  pA = pB;

  pA->f();   // calls B::f


You see that only the last two samples are using virtuality but actually could have used the derived objects also. Using baseclass pointers and virtuality normally is used if you have containers that could contain pointers of different derived objects but where your program doesn't know at runtime which derived object actually was stored.

Regards, Alex

 
 
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 13556579
>>>> Otherwise you would have to create a static function for each derived class.

But the questioner says that he needs two different implementations of the thread functionality. And I couldn't see any baseclass pointer involved til now.

Regards, Alex

0
 
LVL 30

Expert Comment

by:Axter
ID: 13556604
>>*But*, the virtuality only comes to play if you call the virtual function using a baseclass pointer of a derived object.

Not true at all.

See following code:
class A
{
public:
      virtual void f() { cout << "A::f" << endl; }  
      void SomeBaseFunction(){ f(); }
};

class B : public A
{
public:
      virtual void f() { cout << "B::f" << endl; }      
};

class C : public A
{
public:
      virtual void f() { cout << "C::f" << endl; }      
      void g()          { f(); }
};



int main(int argc, char* argv[])
{
      C c;
      c.SomeBaseFunction();// Indirect call to C::f
      B b;
      b.SomeBaseFunction();// Indirect call to B::f
0
 

Author Comment

by:PMH4514
ID: 13556622
this is what polymorphism is all about right?
0
 
LVL 30

Expert Comment

by:Axter
ID: 13556678
>>But the questioner says that he needs two different implementations of the thread functionality. And I couldn't see
>>any baseclass pointer involved til now.

You don't need a base class pointer.

If you look at my version of your code, I don't use any pointers at all.
But if you want the base class to perform some logic in the correct way, based on possible derived class overriden function, you need the function to be virtual.

So to associated this with CCamera class, if you ever want CCamera class to either call CameraThread derived function directly, or if you want to pass the job of creating the thread to the CCamera class, then you need to have a virtual function so that the correct derived class function gets called.
And the above requirement has nothing to do with using a pointer.
0
 
LVL 30

Expert Comment

by:Axter
ID: 13556713
>>this is what polymorphism is all about right?

That's right.
Using the same code signature to get different results, depending on the object.
0
 

Author Comment

by:PMH4514
ID: 13556757
so if class A implements a method Foo(), and class B is derived from A, and B wants to have its own implementation of Foo() that starts by executing A::Foo(), how does one do that? ie. execute the base class implementation, and then continue on with additional instructions?

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 13556763
Axter has it right. If you want to use a non-virtual baseclass function to create the threads, you need the static/virtual combination from above. That is cause the baseclass member function only should pass a static member function of it's own class and virtuality will call the overridden functions later.  

If you have different functions to create the threads, where the functions already know what derived type is involved,  you also could use static functions of the derived classes as there is no need for virtuality then.

Regards, Alex


 
0
 
LVL 30

Expert Comment

by:Axter
ID: 13556804
>>its own implementation of Foo() that starts by executing A::Foo(), how does one do that?

You call  A::Foo() at the start of derived function.

class B : public A
{
public:
     virtual void f()
     {
        A::Foo(); //Call base class first
        cout << "B::f" << endl;
     }      
};
0
 

Author Comment

by:PMH4514
ID: 13556862
excellent.. easy enough.
0
 

Author Comment

by:PMH4514
ID: 13556896
what about constructors/destructors -can common functionality be placed in the base class constructor/destructor methods? if so how do I call up to that within the derived constructor?
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 13556905
>>>> that starts by executing A::Foo(),

A::Foo() always would call A::Foo() and never B::Foo();

As already said, you need either a baseclass pointer or a baseclass function (non-virtual or not overridden) to get polymorphism. In both cases the decision was at runtime what function was called depending on the object.

So it is

   A* pA = getSomePointerOfADerivedOrBaseClass();
   pA->Foo();     // here B::Foo or A::Foo may be called depending on the return above


   void A::NonVirtualFoo()
   {
        Foo();    // here B::Foo or A::Foo may be called depending on 'this' object

   };



0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 400 total points
ID: 13556997
>>> what about constructors/destructors -can common functionality be placed in the base class
>>> constructor/destructor methods?

Yes, but you can't call virtual functions in the baseclass constructor/destructor. The reason for this is, that all constructors/destructors are called at creation/destruction and not as it is with normal function calls only *one* function. So, at creation of the baseclass in baseclass constructor, the derived object isn't yet available cause the constructor of the derived class gets called later. The destructors also were called in opposite order, the baseclass destructor was last.
0
 
LVL 30

Expert Comment

by:Axter
ID: 13557036
>>> what about constructors/destructors -can common functionality be placed in the base class
>>> constructor/destructor methods?

itsmeandnobodyelse is absolutely right.

You can't call derived (virtual) functions from a constructor or destructor because at that point in the code the derived object does not exist.

0
 

Author Comment

by:PMH4514
ID: 13557064
I see.

how 'about if a function is defined as virtual, has an implementation in the base class, and no implementation in the derived class, and I call pDerived->FunctionOnlyImplementedInBaseClass() - will it get executed? Do I have to implement it still within the base class and merely pass the call up the chain?
0
 
LVL 30

Expert Comment

by:Axter
ID: 13557126
>>how 'about if a function is defined as virtual, has an implementation in the base class, and no implementation in the
>>derived class, and I call pDerived->FunctionOnlyImplementedInBaseClass() - will it get executed?

It will execute the base class function.
That's the beautiy of a regular virtual function.
You can let the base class function do the work, or your derived class can optionally have it's own overritten function do the job.
0
 

Author Comment

by:PMH4514
ID: 13557473
ooooohh..

now I really get what virtual is for.. nice!
0
 

Author Comment

by:PMH4514
ID: 13605073
you guys make it so hard for me to determine points :o)
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 13610111
>>> you guys make it so hard for me to determine points :o)

Increase to 500 and split points ;-)  Isn't it simple?


0
 

Author Comment

by:PMH4514
ID: 13610821
sounds good to me! I learned alot from this discussion
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

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