How to Access a Private Variable?

删除回忆录丶 提交于 2019-12-10 12:03:36

问题


This question isn't meant to sound as blatantly insulting as it probably is right now.

This is a homework assignment, and the spec sheet is scarce and poorly designed to say the least. We have a function:

double refuel( int liter, GasStation *gs )
{
    // TODO: Access private variable MaxFuel of gs and decrement.
}

Sound simple enough? It should be, but the class GasStation comes with no function that accesses the private variable MaxFuel. So how can I access it anyway using the function refuel?

I'm not considering creating a function setFuel( int liter ) because the teacher always complains rather energetically if I change his specification. So... I guess I have to do some sort of hack around it, but I'm not sure how to go about this without explicitely changing the only function in GasStation and giving it a parameter so that I can call it here.

Any hints perhaps?


回答1:


Now that sounds like a real lousy homework assignment.

Anyway, I can think of three ways to access private data:

  1. through public member functions
  2. by a friend of the class
  3. cheating:

    #define private public 
    #include "the_class.h"
    #undef private
    

The first two are legal, but require you to change the class. The last is "non-intrusive" (for some definition of "non-intrusive", anyway), but is definitely illegal (although I have yet to see a compiler were it wouldn't work).




回答2:


Declare refuel(..) as a friend function. Otherwise, you are out of luck.




回答3:


Compile and run a test program. Run it in a debugger and examine the memory layout of GasStation. calculate the exact distance in bytes what the distance from the start of a GasStation to the int you need to set is (note if it's the first thing and there's no virtual functions then that distance is guaranteed to be 0 so you can omit the first few steps).

Use this value to increment the pointer to the position within the object where you need to set the data as Kirill shows. However, just to be an ass--your teacher deserves it--do not use any symbolic language here...use the value of the distance directly like so:

*reinterpret_cast<int*>(reinterpret_cast<char*>(gs)+42);

or whatever 42 should be to get to the right place.

If you really want to be an ass, put a fake variable in your function. Compile and run the program and then find the distance on the stack between this fake variable and the location of the GasStation pointer data. Then do this:

*reinterpret_cast<int*>(reinterpret_cast<char*>(*reinterpret_cast<char**>(reinterpret_cast<char*>(&my_var)-666)) + 42) = new_value;



回答4:


I have a suitably terrible solution for your teacher's terrible assignment.

#define private public
#include "GasStation.h"
#undef private



回答5:


Obviously the point of a GasStation is to offer GasStation::pump(Car&). This will decrement private: unsigned int MaxFuel for you.




回答6:


This is dirty, but you can do:

#define private public
#include "GasStation.h" // Or whatever the name is

Now the compiler thinks everything in that header is public. Joy!




回答7:


Best way is to add public member function to GasStation.

Something less safe is to make refuel a friend function.

Absolutely not safe option is available if you know offset of member MaxFuel in that class. Then you could change it as follows (NEVER DO THIS IN PRODUCTION CODE):

int* max_fuel = reinterpret_cast<int*>( reinterpret_cast<char*>(gs)+MaxFuel_OFFSET );
*max_fuel = new_value;


来源:https://stackoverflow.com/questions/3018201/how-to-access-a-private-variable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!