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.
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.
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
Use getters in your CameraAcquisition class
i.e.
CVSize getSize() { return size; }
CvCapture* getDevice { return device; }
etc...
You could always declare them as friends by adding in the class definition:
friend IplImage * ::grabFrame();
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);
Related
In VS, when you type "class." you are presented with a list of functions you can call. Having to look through a list of 15-20 functions, half or more of which being members is not nice.
I'm extremely interested in finding a system that will hide private member functions or move them to the end of the list, so the user doesn't have to scroll through a list of locked functions.
I have four design types:
1) Namespace method hiding
2) Class based method hiding
3) pimpl version
4) _ prefix
Here is the code for clarity:
#pragma once
#include <memory>
using namespace std; // ignore the fact this is global here
struct Hide_Test_Data
{
int value;
};
namespace Hide_Test_Private_Member_Ns
{
void private_function(Hide_Test_Data& data) {}
};
class Hide_Test_Methods
{
public:
Hide_Test_Methods() {}
void private_function(Hide_Test_Data& data) {}
};
class Hide_Test_Methods_Alt
{
public:
Hide_Test_Methods_Alt() {}
void private_function() {}
private:
Hide_Test_Data htd_;
};
class Hide_Test
{
public:
Hide_Test() {}
void public_function()
{
_private_function(); // member function prefixed with _
Hide_Test_Private_Member_Ns::private_function(htd_); // namespace version
htm_.private_function(htd_); // subclass version (no private data)
pimpl->private_function(); // pimpl version (with private data)
}
private:
Hide_Test_Data htd_; // class to hold data
Hide_Test_Methods htm_; // class to hold methods
void _private_function() {}; // _ prefixed member function
unique_ptr<Hide_Test_Methods_Alt> pimpl;
};
Note:
The unique_ptr Hide_Test_Methods_Alt version has member data which the standard one doesn't. Both could be implemented in either way.
The _ prefix doesn't hide the member data, but it does move it to the end of the list. This has the advantage of allowing user to see the private functions if they are interested. My main goal is not to hide the private member functions, just to move them out of the way.
Prefixing data with _ 'should' be safe out of global scope according to the standard as long as it is followed with a lowercase letter.
Which of these designs would be more acceptable in general? I imagine I could work with all four of these design types comfortably, but I would rather hear some input on some of the pros and cons I may not have thought of.
Pimpl uses a pointer to ease copying the member data. In the cases where I don't need to copy the member data, is just using a class better or worse?
I have done some research and found a few related threads in this forum:
Hiding private data members? (C++) - this one points out the pimpl idiom (which I added to my examples above).
How to hide private members of a Class? - talks about VS intellisense not hiding private members
Why does Visual Studio's intellisense show private members and functions? - gives an #ifdef solution that I don't really like the idea of.
I think this question is different enough from the others presented to be worthy posting. Thanks as always.
Generally a pimpl pattern is applied when you want to be able to change implementations at link time and as such must be a pointer
Here you don't want the overhead, so you could consider an inner class and an instance of that class as opposed to a pointer:
class fewfunctions
{
class manyfunctions
{
public:
int a1() { return 0; }
int a2() { return 0; }
int a3() { return 0; }
int a4() { return 0; }
// ... many more
};
public:
int b() { return a.a1() + a.a2() + a.a3() +a.a4(); }
private:
manyfunctions a;
};
Only b will show up as a function (a shows up as locked)
I'm new to C++ and I'm having trouble with this. So I'm trying to make classes that can call on each other's fields using a generic subclass.
Basically, I'm trying to make a game where there is a generic type and three types that have strengths/weaknesses against each other. I only really have experience in Java, and the translation to c++ for this kind of thing isn't clicking for me
Generic type splits into three types: type 1, type 2, type 3.
Generic type needs to be concrete
In the generic type there are fields attack, defense, hitpoints
types 1, 2, and 3 all inherit these fields.
I'm trying to make a virtual function in the generic class:
virtual void attack(Generic* g);
Problem is, when I try to make type_1.attack(generic) for example, I want to do g->hitpoints to get generic's hitpoints, but it just doesn't seem to work like that in C++.
Additionally, I know I must be doing something wrong, because type 1, 2 and 3 all include the generic type's header, but if I want to include those 3 headers in main.cpp, it'll give me an error for declaring generic 3 separate times.
How would I go about doing this?
Sorry this is a very specific question and it's a little bit vague. Please let me know if I need to clarify anything
Edit: Here is the basic setup of what I'm talking about
//in generic.h
class Generic {
protected:
int hitpoints;
int strength;
int defense;
public:
virtual void attack(Generic* g);
};
//type1.h
#include 'generic.h'
class Type1 : public Generic {
void attack (Generic* g);
};
//in type1.cpp
void Type1::attack(Generic*g) {
g->hitpoints = strength - g->defense;
}
An object can access its own protected members that are inherited from a base class. But an object cannot access another object's protected members. That is the difference between private vs protected - private members can only be accessed by the class that declares them, but protected members can be accessed by the declaring class and its descendants. Both are still private to outside code, though.
To do what you are attempting, hitpoints needs to be public.
type 1, 2 and 3 all include the generic type's header, but if I want to include those 3 headers in main.cpp, it'll give me an error for declaring generic 3 separate times.'
You need to make sure that the class is declared only once. This is usually done with guards in the .h file:
//generic.h
#ifndef GENERIC_H
#define GENERIC_H
//all declarations go here
#endif /* GENERIC_H */
When you type #include "generic.h", the C++ processor will basically just paste the contents of foo.h. Since you included it thrice (via the includes for classes Type1, Type2 and Type3, that each include generic.h), the class is delcared three times.
You should do something like this:
// generic.h
#pragma once
class Generic {
protected:
int hitpoints_;
int strength_;
int defense_;
void do_damage(Generic* g, int damage) { g->hitpoints_ -= damage; }
public:
virtual void attack(Generic* g) = 0;
int hitpoints() const { return hitpoints_; }
int strength() const { return strength_; }
int defense() const { return defense_; }
};
// type1.cpp
void Type1::attack(Generic* g) {
do_damage(g, strength_ - g->defense());
}
To avoid your second problem (a class defined multiple times), there is something called include guards (they guard you from including the same file several times). It works like this way:
// File: type1.h
// At the very beginning
#ifndef type1_h
#define type1_h
// Here come the rest of your file and, at the end:
#endif
This way, the contents of the file are only included once, because after that type1_h will be defined, so everything will be skipped. This may be the only use of #define that is universally accepted in C++.
As for your first problem, protected means that derived classes can read that member for themselves or objects of their own class, but nobody else. This includes that derived classes cannot read that member for objects belonging to another class, including the base class itself. I'm afraid you'll have to rethink your design.
The best that you can do is just changing the privacy of the protected members or, even better, provide public accessors and keep the data members private. public data members are seldom a good idea in classes (structs are a different thing):
class Generic {
private:
int hitpoints;
int strength;
int defense;
public:
virtual void attack(Generic* g);
void SetHitpoints(int hp) {hitpoints = hp;}
int GetDefense() {return defense;}
};
The meaning of protected for data members is subtly different from what you might expect. When you have a class A with a protected data member d and a class B that inherits from A (with public inheritance), then B's member functions can access d – but only on objects of type B, not on any object of type A. If that seems confusing, a code example will hopefully make it clearer:
class A {
protected:
int d;
};
class B : public A {
void fine(B& b) { b.d = 0; }
void wrong(A& a) { a.d = 0; }
};
int main() { }
As the names indicate, the assignment in functions fine is ok, but you'll get a compiler error for the one in wrong if you try to compile the code. The best way to deal with this is probably to make the data members private and write protected member functions that operate on them, as in abyss.7's answer.
For the double inclusion problem, use either include guards or #pragma once.
I would like to know if a friend function can change private data in the class without using a
pointer and sending out the object.
I mean does a friend function have access like a member function?
For Example:
class myinfo {
private:
char name[20];
int id;
float income;
public:
void showInfo(void);
myinfo(void);
friend void updateInfo(myinfo);
int main ( ) {
myinfo j;
updateInfo(j); // calling the friend function
return 0;
}
void updateInfo(myinfo c) {
strcat(c.name, ":updated");
c.id++;
c.income += 1.1;
Yes, but not the way you've written it... If you want the function to modify the passed in object, accept a reference rather than by value...
It appears you've not learned about references in c++.
// Declaration of function in class
friend void updateInfo(myinfo&);
implementation
void updateInfo(myinfo& c)
{
strcat(c.name, ":updated"); // now modifying passed in instance of c.
c.id++;
c.income += 1.1;
}
Btw. on a side note, prefer to use std::string and also learn about rule of three (specially for non-trivial classes such as this).
Yes, In principle, private and protected members of a class cannot be accessed from outside the same class in which they are declared. However, this rule does not affect friends.
Friends are functions or classes declared with the friend keyword.
If we want to declare an external function as friend of a class, thus allowing this function to have access to the private and protected members of this class, we do it by declaring a prototype of this external function within the class, and preceding it with the keyword friend.
See it here - http://www.cplusplus.com/doc/tutorial/inheritance/
#ifndef DATACENTER_H_
#define DATACENTER_H_
#include <map>
#include <list>
#include <string>
#include "LiLo/SoundInfo.h"
#include "MutexCondition.h"
#include "UserInfo.h"
using namespace std;
class DataCenter : MutexCondition{
private:
map<long long, list<SoundInfo *> > m_soundListMap;
void add(long long deviceId, SoundInfo* soundInfo);
public:
DataCenter();
virtual ~DataCenter();
static void addSoundInfo(long long deviceId, SoundInfo *soundInfo);
};
#endif /* DATACENTER_H_ */
DataCenter.cpp file
#include "DataCenter.h"
DataCenter::DataCenter() {
// TODO Auto-generated constructor stub
}
DataCenter::~DataCenter() {
// TODO Auto-generated destructor stub
}
void DataCenter::addSoundInfo(long long deviceId, SoundInfo *soundInfo){
add(deviceId, soundInfo);
}
void DataCenter::add(long long deviceId, SoundInfo *soundInfo){
list<SoundInfo*>& info_list = m_soundListMap[55];
}
I am trying to access the function call addSoundInfo from other classes so I have set this as static. Since the m_soundListMap is not a static so I think I need another function to access to the local data structure.
Inside of the static function, I call add function to add SoundInfo to the list. However, I am getting an error in the static function and it says "Can not call member function .... without object".
How do I fix this problem? Thanks in advance..
If you want to access addSoundInfo from other classes, you need to make it public, or make those other classes friends of DataCenter. static has nothing to with access control.
A static function is not bound to an instance of the class it belongs to, and thus can not access members of that class (it also can not call member-functions). If you really want to access members from a static function, you have to pass an instance of the class as argument the the static function explicitly.
If you struggle with such basic concepts, you should read a good book.
I suppose you mean you don't want to make void add() public and still you want to access it from some classes. It is nothing wrong with that and you can do it this way:
class A
{
private:
void DoPrivateStuf() {}
friend class B; // now B can access A private stuf
};
class B
{
// can have any modifier: public, private, protected depending on your needs
public:
void DoPrivateStufToA( A& a )
{
a.DoPrivateStuf();
}
};
The code seems hopelessly jumbled, but technically you just need to remove the word static. Then you can call dc.addSoundInfo( id, pSoundInfo ) where dc is a DataCenter object.
Cheers & hth.,
static is a way to instruct the compiler "the following function is not manipulating instance variable, only things that are global to all the instances of this class". You use that when you need to keep your constructor private for some reason, or have a function that does instances management (registration, etc.)
When you intend to have only one instance of a given class (e.g. because it is a resource manager), you usually prefer to follow the singleton pattern: a static getInstance() method that return the only instance of that class and create it if needed, then you keep your other methods regular methods and your state instance members.
As others have said, making addSoundInfo() public is enough for it to be available from other class. I'll just add some points about C++'s keyword static. Basically, it has many meanings depending on where is it used. When one uses it for functions, there are two meanings:
static class function: a function that is tied to a class, not any specific object. In this sense, it is similar to namespace concept - using the scope :: operator to access the function.
static function: The function has internal linkage, which means it is only visible in current translation unit (current source file). It is handy for utility functions.
In your case, the answer to your question will technically be something like this:
In the header file:
class DataCenter
{
static void addSoundInfo(DataCenter& dc, long long deviceId, SoundInfo *soundInfo);
}
In the source file:
void DataCenter::addSoundInfo(DataCenter& dc, long long deviceId, SoundInfo *soundInfo)
{
dc.add(deviceId, soundInfo);
}
But it is probably not what you want.
Is it possible to declare a member function of a forward-declared class as friend? I am trying to do the following:
class BigComplicatedClass;
class Storage {
int data_;
public:
int data() { return data_; }
// OK, but provides too broad access:
friend class BigComplicatedClass;
// ERROR "invalid use of incomplete type":
friend void BigComplicatedClass::ModifyStorage();
};
So the goal is to (i) restrict the friend declaration to a single method, and (ii) not to include the definition of the complicated class to reduce compile time.
One approach might be to add a class acting as an intermediary:
// In Storage.h:
class BigComplicatedClass_Helper;
class Storage {
// (...)
friend class BigComplicatedClass_Helper;
};
// In BigComplicatedClass.h:
class BigComplicatedClass_Helper {
static int &AccessData(Storage &storage) { return storage.data_; }
friend void BigComplicatedClass::ModifyStorage();
};
However, this seems a bit clumsy... so I assume that there must be a better solution!
As #Ben says, it's not possible, but you can give specific access just to that member function through a "passkey". It works a bit like the intermediate helper class, but is imho clearer:
// Storage.h
// forward declare the passkey
class StorageDataKey;
class Storage {
int data_;
public:
int data() { return data_; }
// only functions that can pass the key to this function have access
// and get the data as a reference
int& data(StorageDataKey const&){ return data_; }
};
// BigComplicatedClass.cpp
#include "BigComplicatedClass.h"
#include "Storage.h"
// define the passkey
class StorageDataKey{
StorageDataKey(){} // default ctor private
StorageDataKey(const StorageDataKey&){} // copy ctor private
// grant access to one method
friend void BigComplicatedClass::ModifyStorage();
};
void BigComplicatedClass::ModifyStorage(){
int& data = storage_.data(StorageDataKey());
// ...
}
No, you can't declare individual member functions as friends until they've been declared. You can only befriend the entire class.
It may or may not be relevant here, but it is useful to remind ourselves that there is a wild world beyond the scope of classes and objects where functions can roam free.
For example, I recently needed to close off a (singleton global static) system error log from a global exception handler based on a port of someone else's code. The normal include file for my error log conflicted with the exception handler code because both wanted to include "windows.h" for reasons I didn't look into. When this and other questions persuaded me I could not make a forward declaration of my ErrorLog class's member functions, what I did was wrap the necessary functions into a global scope function like this:
void WriteUrgentMessageToErrorLog( const char * message )
{
ErrorLog::LogSimpleMessage( message );
ErrorLog::FlushAccumulatedMessagesToDisk();
}
Some people are very particular about maintaining the integrity of their class structure at all cost... and seldom acknowledge that applications using those classes are inevitably built on top of something that lacks that structure. But it's out there, and used judiciously, it has its place.
Given the age of this question, I have not looked deeply into its relevance here. All I wanted to share was the opinion that sometimes a simple wrapping mechanism like this is a much cleaner and more readily understood alternative to something that has a lot more subtlety and cleverness about it. Subtlety and cleverness tends to get changed at some later date by someone required to add to it who didn't fully understand it. Before you know it, you have a bug...