943,865 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 2167
  • C++ RSS
You are currently viewing page 1 of this multi-page discussion thread
Jun 27th, 2007
0

using pointers

Expand Post »
I have a Class Personnel and a sub-class Student
how could i change a pointer pointing to Personnel and have it point to Student?

I'm trying this

cpp Syntax (Toggle Plain Text)
  1. Personnel *person=NULL;
  2. PersonnelNode *node=NULL;
  3. PersonnelNode *temp, *prev;
  4. Student *s=new Student();
  5. while (temp != NULL) {
  6. person = temp->getNode();
  7. if (stricmp(name,name)==0){
  8. prev = temp;
  9. temp = temp->getNext();
  10. index++;
  11. }
  12. else{
  13. cout <<"Person to delete is found at index" << index<<endl;
  14. display_node(person, index);
  15. s=person;
  16. s->bookQueue->enqueue(title, due);
  17. }
  18.  
  19. }
but it says as an error

error C2440: '=' : cannot convert from 'Personnel *' to 'Student *'
Last edited by WolfPack; Jun 27th, 2007 at 5:56 am. Reason: Added [CODE][/CODE] tags. Learn to use them yourself next time.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
vladdy19 is offline Offline
20 posts
since Jun 2007
Jun 27th, 2007
0

Re: using pointers

Objects of type Personnel can not be converted to PersonnelNode because it knows nothing about the data and methods of the child class. Its a matter of inherentence -- PersonnelNode inherits from Personnel, not the other way around.
Sponsor
Team Colleague
Featured Poster
Reputation Points: 5608
Solved Threads: 2282
Retired and Enjoying Life
Ancient Dragon is offline Offline
21,951 posts
since Aug 2005
Jun 27th, 2007
0

Re: using pointers

Quote ...
how could i change a pointer pointing to Personnel and have it point to Student?
You can typecast it.
C++ Syntax (Toggle Plain Text)
  1. s = (Student*)person;
Reputation Points: 180
Solved Threads: 34
Posting Whiz
Hamrick is offline Offline
322 posts
since Jun 2007
Jun 27th, 2007
0

Re: using pointers

A pointer pointing to base class can be converted to a pointer pointing to derived class (down-casting) if the original pointer is actually pointing to a derived class type.
To enforce this is the work of dynamic_cast operator.

Consider following example.
cpp Syntax (Toggle Plain Text)
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. class base
  6. {
  7. public:
  8. virtual ~base() {cout << "Inside ~base()" << endl ;}
  9. virtual void some_function() {cout << "Inside base::some_function()" << endl ;}
  10. };
  11.  
  12. class derived : public base
  13. {
  14. public:
  15. ~derived() {cout << "Inside ~derived()" << endl ;}
  16. void some_function() {cout << "Inside derived::some_function()" << endl ;}
  17. void special_function() {cout << "Inside derived::special_function()" << endl ;}
  18. };
  19.  
  20. void free_function( base *pb )
  21. {
  22. pb->some_function() ;
  23. //special case, when we need to do something with derived class..
  24. //example of bad OOD. :)
  25. derived *converted_pd = dynamic_cast< derived* > ( pb ) ;
  26. if( 0 != converted_pd )
  27. converted_pd->special_function() ;
  28. else
  29. cout << "dynamic_cast returned NULL. pb was NOT pointing to an obj of type derived." << endl ;
  30. }
  31.  
  32. int main()
  33. {
  34. derived *pd = new derived() ;
  35. base *pb = new base() ;
  36. base *converted_pb = dynamic_cast<base*>( pd ) ;
  37.  
  38. cout << "Calling free_function() with converted_pb." << endl ;
  39. free_function(converted_pb) ;
  40.  
  41. cout << "Calling free_function() with pb." << endl ;
  42. free_function(pb) ;
  43.  
  44. return 0 ;
  45. }
Here is my output:
Calling free_function() with converted_pb.
Inside derived::some_function()
Inside derived::special_function()
Calling free_function() with pb.
Inside base::some_function()
dynamic_cast returned NULL. pb was NOT pointing to an obj of type derived.

Press ENTER to continue.

Objects of type Personnel can not be converted to PersonnelNode
I think it's a typo?? If not it's correct but irrelevant.
Last edited by thekashyap; Jun 27th, 2007 at 9:50 am.
Reputation Points: 254
Solved Threads: 74
Practically a Posting Shark
thekashyap is offline Offline
804 posts
since Feb 2007
Jun 27th, 2007
0

Re: using pointers

Click to Expand / Collapse  Quote originally posted by Hamrick ...
You can typecast it.
C++ Syntax (Toggle Plain Text)
  1. s = (Student*)person;
One shouldn't do this in C++. Use C++ style casting instead (of C-style)
Reputation Points: 254
Solved Threads: 74
Practically a Posting Shark
thekashyap is offline Offline
804 posts
since Feb 2007
Jun 27th, 2007
0

Re: using pointers

Quote ...
Use C++ style casting instead (of C-style)
Why? They do the same thing. And C++ typecasts are too long.
Reputation Points: 180
Solved Threads: 34
Posting Whiz
Hamrick is offline Offline
322 posts
since Jun 2007
Jun 27th, 2007
0

Re: using pointers

Click to Expand / Collapse  Quote originally posted by Hamrick ...
Why? They do the same thing. And C++ typecasts are too long.
In very gentle words NO.
Output of this code:
cpp Syntax (Toggle Plain Text)
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. class base
  6. {
  7. public:
  8. virtual ~base() {cout << "Inside ~base()" << endl ;}
  9. virtual void some_function() {cout << "Inside base::some_function()" << endl ;}
  10. };
  11.  
  12. class derived : public base
  13. {
  14. public:
  15. ~derived() {cout << "Inside ~derived()" << endl ;}
  16. void some_function() {cout << "Inside derived::some_function()" << endl ;}
  17. void special_function() {cout << "Inside derived::special_function()" << endl ;}
  18. };
  19.  
  20. void free_function( base *pb )
  21. {
  22. pb->some_function() ;
  23. //special case, when we need to do something with derived class..
  24. //example of bad OOD. :)
  25. derived *converted_pd = dynamic_cast< derived* > ( pb ) ;
  26. if( 0 != converted_pd )
  27. converted_pd->special_function() ;
  28. else
  29. cout << "dynamic_cast returned NULL. pb was NOT pointing to an obj of type derived." << endl ;
  30.  
  31. cout << endl << "Doing C-style casting" << endl ;
  32. converted_pd = (derived*) pb ;
  33. if( 0 != converted_pd )
  34. converted_pd->special_function() ;
  35. else
  36. cout << "C-style cast returned NULL. pb was NOT pointing to an obj of type derived." << endl ;
  37. }
  38.  
  39. int main()
  40. {
  41. derived *pd = new derived() ;
  42. base *pb = new base() ;
  43. base *converted_pb = dynamic_cast<base*>( pd ) ;
  44.  
  45. cout << endl << "Calling free_function() with converted_pb." << endl ;
  46. free_function(converted_pb) ;
  47.  
  48. cout << endl << "Calling free_function() with pb." << endl ;
  49. free_function(pb) ;
  50.  
  51. return 0 ;
  52. }
is this:
-----------
Calling free_function() with converted_pb.
Inside derived::some_function()
Inside derived::special_function()

Doing C-style casting
Inside derived::special_function()

Calling free_function() with pb.
Inside base::some_function()
dynamic_cast returned NULL. pb was NOT pointing to an obj of type derived.

Doing C-style casting
Inside derived::special_function()

Press ENTER to continue.
-----------
There is your difference and I'm sure you understand the problems associated with it. If not I will explain.
Last edited by thekashyap; Jun 27th, 2007 at 10:08 am. Reason: fixed closing code tag
Reputation Points: 254
Solved Threads: 74
Practically a Posting Shark
thekashyap is offline Offline
804 posts
since Feb 2007
Jun 27th, 2007
0

Re: using pointers

If you know that the conversion works, it doesn't matter, right? If you don't know, you shouldn't be trying to typecast anyway.
Reputation Points: 180
Solved Threads: 34
Posting Whiz
Hamrick is offline Offline
322 posts
since Jun 2007
Jun 28th, 2007
1

Re: using pointers

Click to Expand / Collapse  Quote originally posted by Hamrick ...
If you know that the conversion works, it doesn't matter, right?
Now that's perfect question to be answered with someone's signature (I really searched for it and couldn't find) which goes something like:
"Although it might be possible to collect the twigs using your nose, it doesn't necessarily mean it's the best way."
I'm assuming you didn't see the problem.
------------------------------------------
Calling free_function() with pb. => Remember pb points to object of type base, which does not implement a function named special_function().

Inside base::some_function()
dynamic_cast returned NULL. pb was NOT pointing to an obj of type derived. => dynamic_cast knows that pb can not and must not be converted to derived*, so it returns NULL.

Doing C-style casting
Inside derived::special_function() => Even though this object does not have this function a call to it is successful. This is only bad-luck.
------------------------------------------
Now if you still doesn't see the problem, let me give you another one:
cpp Syntax (Toggle Plain Text)
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. enum ActionEnum { GET_LAN_STATUS,
  6. SHUTDOWN_LAN
  7. } ;
  8.  
  9. class employee
  10. {
  11. public:
  12. employee(const string nameStr):name(nameStr) {}
  13. virtual ~employee() {cout << "Inside ~employee()" << endl ;}
  14. virtual void get_status_of_office_LAN() {cout << "get_status_of_office_LAN() by: " << name.c_str() << endl ;}
  15. string getname() { return name ; }
  16. protected:
  17. string name ;
  18. };
  19.  
  20. class administrator : public employee
  21. {
  22. public:
  23. administrator(const string nameStr):employee(nameStr) {}
  24. ~administrator() {cout << "Inside ~administrator()" << endl ;}
  25. void get_status_of_office_LAN() {cout << "get_status_of_office_LAN() by: " << name.c_str() << endl ;}
  26. void shutdown_office_LAN() {cout << "LAN shutdown by: " << name.c_str() << endl ;}
  27. };
  28.  
  29. void perform_action( employee *pb, ActionEnum action )
  30. {
  31. switch( action )
  32. {
  33. case GET_LAN_STATUS:
  34. {
  35. pb->get_status_of_office_LAN() ;
  36. break ;
  37. }
  38.  
  39. case SHUTDOWN_LAN:
  40. {
  41. administrator *converted_pd = dynamic_cast< administrator* > ( pb ) ;
  42. if( 0 != converted_pd )
  43. converted_pd->shutdown_office_LAN() ;
  44. else
  45. cout << pb->getname().c_str() << ": does not have required rights to shutdown LAN." << endl ;
  46.  
  47. cout << endl << "Doing C-style casting" << endl ;
  48. converted_pd = (administrator*) pb ;
  49. if( 0 != converted_pd )
  50. converted_pd->shutdown_office_LAN() ;
  51. else
  52. cout << pb->getname().c_str() << ": does not have required rights to shutdown LAN." << endl ;
  53. }
  54. default: break;
  55. }
  56. }
  57.  
  58. int main()
  59. {
  60. administrator *pd = new administrator("Some administrator") ;
  61. employee *pb = new employee("NOT an administrator") ;
  62.  
  63. cout << endl << "Calling perform_action(GET_LAN_STATUS) with pb." << endl ;
  64. perform_action(pb, GET_LAN_STATUS) ;
  65. cout << endl << "Calling perform_action(SHUTDOWN_LAN) with pb." << endl ;
  66. perform_action(pb, SHUTDOWN_LAN) ;
  67.  
  68. return 0 ;
  69. }
and here is the output:
----------------------------------------------------------
Calling perform_action(GET_LAN_STATUS) with pb.
get_status_of_office_LAN() by: NOT an administrator

Calling perform_action(SHUTDOWN_LAN) with pb.
NOT an administrator: does not have required rights to shutdown LAN.

Doing C-style casting
LAN shutdown by: NOT an administrator

Press ENTER to continue.
----------------------------------------------------------
Reputation Points: 254
Solved Threads: 74
Practically a Posting Shark
thekashyap is offline Offline
804 posts
since Feb 2007
Jun 28th, 2007
0

Re: using pointers

Oh. Okay.
Reputation Points: 180
Solved Threads: 34
Posting Whiz
Hamrick is offline Offline
322 posts
since Jun 2007

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: How do I initialize an array from infile?
Next Thread in C++ Forum Timeline: Help me plz, LIST CONTROL





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC