4

I'd like to know if there's any way to access a private member of a class from outside the class. I'll explain my problem.

I have a .hpp file which contains the definition of the class along with its private members and public function (which are the only one I'd like to export). In the corrisponding .cpp I have to use some "support" function which need access to the private members of the class defined in the .hpp.

Here's part of my code:

--- .hpp ---

namespace vision {
class CameraAcquisition {

    /* MEMBERS */
    CvSize size;
    CvCapture *device;
    CvScalar hsv_min,hsv_min2,hsv_max,hsv_max2;

    /* METHODS */

public:
    CameraAcquisition();
    ~CameraAcquisition();
    int findBall();
};
}

--- .cpp ---

#include "CameraAcquisition.hpp"

using namespace vision;

IplImage *grabFrame() {
     // code here
}

IplImage *convertToHSV(IplImage *origin) {
// code here
}

IplImage *calculateThresholdedImage(IplImage *converted) {
// code here
}

What I need is for these three functions to access the members of the class CameraAcquisition. Is there any way to do it? Any suggestions will be appreciated. Thank you all

EDIT Sorry, I forgot an important piece of information here. In the source file, findBall() must call those methods. I defined those methods to make the code easier to read. I cannot declare those methods in the class definition because I don't want to export them. If I declare them in a "private" block everything works fine, but maybe it's not correct to that (I don't see the point in providing an header file with private methods.

paxilpaz
  • 421
  • 2
  • 5
  • 7
  • Can you change the header files involved? If you can & there exists an strong coupling between the two classes then you can use `friend`ship,Note that `friend`ship enhances encapsulation in this case rather than breaking it as some may suggest & it is far better an option than encapsulation breaking getter, setter methods or dangerous hackery with macros.Just don't opt for those,write code which is readable and maintainable instead of weird stuff which no one except you can understand/maintain in future. – Alok Save May 15 '12 at 14:40
  • possible duplicate of [access private member using template trick](http://stackoverflow.com/questions/12993219/access-private-member-using-template-trick) – bames53 Oct 01 '13 at 16:32

5 Answers5

3

If those members are made private and you need access to them, you're doing something wrong, so my suggestion is that you don't.

Now let's get serious - there are some ways - DISCLAIMER: not all are safe or portable or guaranteed to work:

1) Preprocessor abuse

#define class struct
#define private public
#include "CameraAcquisition.h"
#undef class
#undef private

2) Fake class

class MyCameraAcquisition {
public: //<--- public in your class
    /* MEMBERS */
    CvSize size;
    CvCapture *device;
    CvScalar hsv_min,hsv_min2,hsv_max,hsv_max2;

    /* METHODS */

public:
    CameraAcquisition();
    ~CameraAcquisition();
    int findBall();
};

CameraAcquisition prvt;
MyCameraAcquisition publ = (MyCameraAcquisition&) prvt;

3) Template abuse posted by litb - http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html

This one is, actually, and surprisingly, standard-compliant.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
2

You should not want to access private mebers of objects. Consider providing public getter/setter member functions that outside code can use to affect the private member variables

Alternatively, you can make your support function a member of the class, so it has automatic access to the private members.

If you really want to access private members, you can use the friend keyword to declare another class or function as friend of the current class

class A
{
  int a; // private
  friend class B;
  friend void f(A*);
};

Here both class B (i.e. its member functions) and free function f can access A::a

Attila
  • 28,265
  • 3
  • 46
  • 55
  • 1
    If he could add `friend`, I'm sure he could make the members `public`. – Luchian Grigore May 15 '12 at 14:32
  • 1
    But there _is_ a difference between making your members public for all to see/change and declaring a few trusted `friend`s – Attila May 15 '12 at 14:36
  • I know there is, but It's not really clear whether he has can change the headers. – Luchian Grigore May 15 '12 at 14:37
  • I do not want to change the header, that's what I'd like to export. I could declare those functions in a private block, but it just doesn't seem right to present a header file with "private" functions the final user shouldn't even know are there – paxilpaz May 15 '12 at 18:02
  • Having `private` members in a class definition is perfectly normal. If you wanted to hide the actual implementation, look up the PIMPL idiom (Private IMPLementation -- basically ou have a forward declared struct that contains all private implementation details and the class holds a (private) pointer to that struct; the actual definition of the stuct is in the corresponding implementation .cpp) – Attila May 15 '12 at 18:06
0

Use getters in your CameraAcquisition class

i.e.

CVSize getSize() { return size; }

CvCapture* getDevice { return device; }

etc...

Carl Winder
  • 938
  • 8
  • 18
0

You could always declare them as friends by adding in the class definition:

friend IplImage * ::grabFrame();
slartibartfast
  • 4,348
  • 5
  • 31
  • 46
0

Compiler used is Visual Studio 2015
This method is not recommended but works.
Lets consider following class

class mydata
{
    private:
    int x;
    public:
    mydata(int no)
    {
        x=no;
    }
}

Only data members are stored in the class object. Now I can access the x using following function. As I know that class mydata has only one variable it must be the int x.

int getx(mydata *d)
{
    return ((int*)d)[0];

    /*
    How did this work?
    -> d is pointing to the mydata object. 
    as I typecasted it to int* it will be considered as int array.
    Of that array (which has lenght 1) access the first element.
    */
}

If there was another variable lets say y of type DATATYPE.
Now, to access y we have to calculate the offset of it from the base of object.

Usually data is stored in the same order in which you declare it.
Also, there is struct padding to be considered in case of heterogeneous data types in the class. I would like to suggest you to read struct padding in depth.

And the we can get y as

myclass *ptr =new myclass();
int offset_y=//whatever offset of y in number of bytes from base of object of perticular class;
char *byte_ptr_y=((char*)ptr)[offset_y];
DATATYPE y=*((DATATYPE*)byte_ptr_y);
Santosh Kale
  • 113
  • 12