home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / cplus / 12514 < prev    next >
Encoding:
Text File  |  1992-08-18  |  3.8 KB  |  121 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!usc!zaphod.mps.ohio-state.edu!moe.ksu.ksu.edu!ux1.cso.uiuc.edu!uchinews!msuinfo!pacific.cps.msu.edu!baldwin
  3. From: baldwin@pacific.cps.msu.edu (Reid A Baldwin)
  4. Subject: Re: Virtual Functions and Shared Memory
  5. Message-ID: <1992Aug18.175629.15693@msuinfo.cl.msu.edu>
  6. Sender: news@msuinfo.cl.msu.edu
  7. Organization: Dept. of Computer Science, Michigan State University
  8. References: <1992Aug17.145104.5729@edrc.ac.uk> <1992Aug17.182423.14341@msuinfo.cl.msu.edu>
  9. Date: Tue, 18 Aug 92 17:56:29 GMT
  10. Lines: 109
  11.  
  12. In article <1992Aug17.182423.14341@msuinfo.cl.msu.edu>, I write:
  13. |> I am developing an application in which multiple processes communicate
  14. |> via shared memory (UNIX). Unfortunately, virtual functions don't work for
  15. |> objects in shared memory. The process that creates an object gets the
  16. |> correct results, but other processes execute the function for the
  17. |> base class instead of the derived class (using the pointer type instead
  18. |> of the object type). I am not familiar with the implementation of virtual
  19. |> functions. Is it possible to use virtual functions on objects that are
  20. |> created by other processes and accessed via shared memory?
  21. |> 
  22. |> Thanks for your help,
  23. |> Reid Baldwin
  24. |> 
  25. |> P.S. I will post a summary of responses if they are interesting.
  26.  
  27. Well, I solved it with a little help from
  28. john%tollys.UUCP%bnrmtl.UUCP@Larry.McRCIM.McGill.EDU (John Hickin)
  29. who responded:
  30.  
  31. >I am surprised that it works at all.  Normally i would expect a core dump but
  32. >that may depend on the implementation.  cfront, for example, adds a pointer to
  33. >each object using virtuals (actually there can be more than one such pointer
  34. >if you are using multiple inheritance).  This pointer references a table of
  35. >member function pointers.  Unfortunately, this virtual function table is in
  36. >the memory space of the process which created the object.  Passing the object
  37. >to another process through shared memory and running a virtual function can
  38. >cause a segmentation violation.  If the processes involved are related via a
  39. >fork (without an exec) and your brand of unix implements a copy-on-write policy
  40. >for the parent's memory, then the child process can access the parent's virtual
  41. >function tables without problem.
  42.  
  43. Here is what I wanted:
  44.  
  45. class first {
  46.   char _name[10];
  47.  :public
  48.   first(char *name) {
  49.     strncpy(_name, name, 10);
  50.   }
  51.   ~first();
  52.   virtual void print() {
  53.     printf("first %s\n", _name);
  54.   };
  55. };
  56.  
  57. class second : public first {
  58.   char _name[10];
  59.  :public
  60.   second(char *name) : first(name) {};
  61.   ~second();
  62.   void print() {
  63.     printf("second %s\n", _name);
  64.   };
  65. };
  66.  
  67. Here is what I had to do to get it:
  68.  
  69. first first_dummy("dummy");
  70. second second_dummy("dummy");
  71. class Vfirst {
  72.  :public
  73.   first *_list[2];
  74.   Vfirst() {
  75.     _list[0] = &first_dummy;
  76.     _list[1] = &second_dummy;
  77.   }
  78. } dummies;
  79.  
  80. class first {
  81.   char _name[10];
  82.  :protected
  83.   int _typind; /* indicates what type object is */
  84.  :public
  85.   first(char *name) {
  86.     strncpy(_name, name, 10);
  87.     _typind = 0;
  88.   }
  89.   ~first();
  90.   void print() {
  91.     dummies.list[_typind]->print(this);
  92.   };
  93.   virtual void print(first *it) {
  94.     this = it;
  95.     printf("first %s\n", _name);
  96.   };
  97. };
  98.  
  99. class second : public first {
  100.  :public
  101.   second(char *name) : first(name) {
  102.     _typind = 1;
  103.   };
  104.   ~second();
  105.   void print(first *it) {
  106.     this = (second *) it;
  107.     printf("second %s\n", _name);
  108.   };
  109. };
  110.  
  111.  
  112. Basically, I never call the virtual function for an object in shared
  113. memory. Instead, the print() function calls the print(first *) function
  114. for an object in the processes own address space that has the same type
  115. as the object in shared memory. This ensures that the correct function
  116. is called. The object address must be passed explicitly instead of
  117. relying on C++ to pass it implicitly. Unfortunately, I have to do some
  118. extra stuff each time I make a new subclass or make a new virtual function.
  119.  
  120. Reid Baldwin
  121.