Link to home
Start Free TrialLog in
Avatar of Ben Jabroni
Ben Jabroni

asked on

C++ help/ Toy problem

Hi, I am trying to learn c++ and I am stuck on this toy problem. It is not a trick, there is a working solution in the given constraints, but it is a little tricky and unorthodox I think. The pointers, virtual tables, and public/private methods are really giving me a hard time.

Here is the problem:

Only writing code where indicated and without defining any new classes, try to get the program to output the following things (only one at a time, since there is only one return value):

Here is the code:

#include <cstdio>

class Thing
{
private:
      int x;
      int y;
      virtual int doStuff()
      {
            return x+y;
      }
      virtual int doStuff2()
      {
            return x*y;
      }
public:
      Thing(){
            x = 2;
            y = 10;
      }
};

int extractThing(void* thing)
{
      //insert code here
      //return the value to be printed
}

int main()
{
      Thing thing;
      printf("%d\n", extractThing(&thing));
      return 0;
}
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

So, what have you done so far?

Oh, you also seem to have left out the list of things it's supposed to output (unless I misunderstood your post).
Avatar of Ben Jabroni
Ben Jabroni

ASKER

int extractThing(void* thing)
{
      //insert code here
      //return the value to be printed
      
    int *pInt = static_cast<int*>(thing);
    int obj = *pInt;
 

 
    // *intPtr.(&thing).Thing();
    std::cout << thing;
    return 0;

// thing * p = whatever(); // pointer to object
// void * pv = p;          // pointer to void
// thing * p2 = static_cast<thing *>(pv);
   
      
}


I have just been trying to access the object methods and I have pretty much only been able to print out the pointer but I have tried many many things and I can't seem to understand how to access the object methods.
there are some comments there of things I tried that can be ignored
Only writing code where indicated and without defining any new classes, try to get the program to output the following things (only one at a time, since there is only one return value):

thing.x
thing.y
thing.doStuff()
thing.doStuff2()
ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>> you won't be able to access then directly in that way
In fact, there is NO standard C++ way to access private members except via member functions. If you are allowed to add to the existing class you can add public accesser functions to provide access to them.
Yes it does, I still get a similar error to what I have been getting though:

layout.cpp:34:10: error: member reference base type 'void' is not a structure or
      union
    thing->doStuff();
    ~~~~~^ ~~~~~~~


code:
int extractThing(void* thing)
{
      //insert code here
      //return the value to be printed
      
    Thing *pInt = reinterpret_cast<Thing *>(thing);
   
    thing->doStuff();
 
    std::cout << thing;
    return 0;
   
      
}
This...

    Thing *pInt = reinterpret_cast<Thing *>(thing);
    thing->doStuff();

Should probably be...

    Thing *pThing = reinterpret_cast<Thing *>(thing);
    pThing ->doStuff();
Thanks very much for the help so far .  Yeah I figured as much... I was told this was not a trick and that there was a solution given the constraints (including not writing code anywhere else)

the problem included this reference material to steer me in the direction of a solution ....

https://en.wikipedia.org/wiki/Virtual_method_table
http://www.openrce.org/articles/full_view/23
https://en.wikipedia.org/wiki/Pointer_(computer_programming)#C_arrays
https://en.wikipedia.org/wiki/Pointer_(computer_programming)#Function_pointer
>>  std::cout << thing;
You can't output thing... it's a pointer to void.
There is a solution; however, virtual functions won't help (at least not with standard C++) because all the member functions are private. I guess the question is trying to get you to mess around with the v-table, but since standard C++ doesn't state virtual functions have to be implemented via a v-table and since the mechanics of how this are done are compiler specific, I can't give you a standard C++ solution for that.
>> There is a solution

Like I said, adding accessor functions to the existing class will be a solution.
What does that solution look like as far as adding the accessor functions? I still need to understand the pointer concept here and other things involved, so I will just modify the problem
Well, what don't you understand about the pointer concept?

By way of completeness, I should also say that adding free-standing friend functions would also solve this.

I have to go out now, if someone else doesn't pick this up I'll get back to you either a little later or tomorrow morning (UK time).
One thing I am struggling with is this:

public:
      
      Thing(){
            x = 2;
            y = 10;
      }

I have been treating this as a function and trying to call it, because I guess I am thinking the variables need to be instantiated before the doStuff functions will even do  anything .. So i dont really understand what that is on the public method of Thing...  I get this error:

layout.cpp:32:14: error: cannot refer to type member 'Thing' in 'Thing' with
      '->'
    pThing ->Thing();
             ^
layout.cpp:4:7: note: member 'Thing' declared here
class Thing
      ^
1 error generated.

this is the code:

int extractThing(void* thing)
{
      //insert code here
      //return the value to be printed
      
    Thing *pThing = reinterpret_cast<Thing *>(thing);
    pThing ->Thing();
 
    std::cout << pThing;
    return 0;
      
}
That's a constructor for the class. It is automatically called when you create the class. When you do this....

Thing thing;

This calls that function to construct the class. You don't need to call it directly (at least, not in this context - there are times when you might, but that doesn't apply here so don't worry about that for now).
So, how are you getting on?
I did it the way you said by adding access functions! I appreciate your help very much! I think I will try and see what I can do as far as the vtable .. they claim that it is solvable and not a trick question, but geez its tough
I'd really be interested to know what they consider the optimal solution to be.

Personally, I dislike assignments like these as they are not really teaching you anything useful nor practical about C++. I sometimes wonder if the people who set these assignments have even read the C++ standard. If they had they should know that an assignment based on manipulating v-tables is teaching you to do something bad. As I said before, the standard is very clear about the fact that how virtual functions are implemented is undefined and the v-table just happens to be the most popular way, but it is not a requirement of the standard and is vendor specific.

Anyway, good luck.