class Point1D { public: Point1D(double x) : x_(x) {}; private: double x_; }; |
class Point2D : public Point1D { public: Point2D(double x, double y) : Point1D(x), y_(y) {}; private: double y_; }; |
Reading/Writing private data directly: (Professional driver, closed course. Don't try this at home.)class Point3D : public Point2D { public: Point3D(double x, double y, double z) : Point2D(x, y), z_(z) {}; private: double z_; };
#include <iostream>
int main(void)
{
Point3D pt3(5, 10, 15);
// Display private members: 5, 10, 15
std::cout << *reinterpret_cast<double *>(&pt3) << ", ";
std::cout << *(reinterpret_cast<double *>(&pt3) + 1) << ", ";
std::cout << *(reinterpret_cast<double *>(&pt3) + 2) << std::endl;
// Modify private members
*reinterpret_cast<double *>(&pt3) = 1;
*(reinterpret_cast<double *>(&pt3) + 1) = 2;
*(reinterpret_cast<double *>(&pt3) + 2) = 3;
// Display private members: 1, 2, 3
std::cout << *reinterpret_cast<double *>(&pt3) << ", ";
std::cout << *(reinterpret_cast<double *>(&pt3) + 1) << ", ";
std::cout << *(reinterpret_cast<double *>(&pt3) + 2) << std::endl;
return 0;
}
Visually, the classes might look like this:#include <iostream> class Point1D { public: Point1D(double x) : x_(x) {} virtual ~Point1D() {} double getX(void) const {return x_;} void setX(double x) {x_ = x;} virtual void Display(void) { std::cout << x_; } private: double x_; }; class Point2D : public Point1D { public: Point2D(double x, double y) : Point1D(x), y_(y) {} virtual ~Point2D() {} double getY(void) const {return y_;} void setY(double y) {y_ = y;} virtual void Display(void) { Point1D::Display(); std::cout << ", " << y_; } virtual void SwapXY(void) { double x = getX(); setX(y_); y_ = x; } private: double y_; }; class Point3D : public Point2D { public: Point3D(double x, double y, double z) : Point2D(x, y), z_(z) {}; virtual ~Point3D() {} double getZ(void) const {return z_;}; void setZ(double z) {z_ = z;} virtual void Display(void) { Point2D::Display(); std::cout << ", " << z_; } virtual void SwapXYZ(void) { double x = getX(); setX(getY()); setY(z_); z_ = x; } private: double z_; };
You can clearly see the extra 4 bytes that are added to each object. Also, the size of the class' corresponding virtual method table is obvious. Things to note:
So, now if we tried to "go through the back door":
We'd get this:Point3D pt3(5, 10, 15); // Display private members: 5, 10, 15 std::cout << *reinterpret_cast<double *>(&pt3) << ", "; std::cout << *(reinterpret_cast<double *>(&pt3) + 1) << ", "; std::cout << *(reinterpret_cast<double *>(&pt3) + 2) << std::endl;
We'd have to do this:-9.25596e+061, 5, 10
The example above "seemed" to work with both Microsoft's 7.1 compiler and GNU's g++ 3.3 compiler. Borland's 5.6 compiler printed the y and z values correctly, but printed garbage for x:// Display private members: 1, 2, 3 std::cout << *reinterpret_cast<double *>(&pt3) << ", "; std::cout << *(reinterpret_cast<double *>(&pt3) + 1) << ", "; std::cout << *(reinterpret_cast<double *>(&pt3) + 2) << std::endl;
5.31147e-315, 10, 15