Suppose I have my classes as:
namespace scope
{
class A
{
private:
int a;
public:
...
};
class B
{
public:
...
A method();
...
};
};
The method definition:
A B::method()
{
A object;
object.a = 3; // private member access error
// access via object (pointer) error if inheritance is used
return object;
}
The most common way to solve the access error is to use setters+getters.
However I don't want any other scope (or someone using the API) to set A.a, so a public setter method is forbidden for this case.
a may be public but it should be read-only on API side. It should be read+write on the source side, because, for instance, I want to set it with B::method. How can I achieve this behaviour?
I tried inheritance, also friend relation. I also played with immutable and const property declarations. The problem with these is, when I declare A object with the default constructor, property is set to some value like -918316838410 (which might arise from the fact that I'm not using extern, I'm not sure) and cannot be set by method later on.
Any ideas will be appreciated. Thanks in advance.
You want B to have access to A that you don't want other people to have?
That is friendship.
Add friend class B, into the class A definition, and all will be happiness.
btw the common examples for this are when I am using multiple classes to generate a single interface. Eg: things like list<> and map<> usually need node classes, and those classes often want friend access on each other. This breach of encapsulation is fine, since they are really one big class from a logical perspective.
Be warned, most people should use friends rarely or never, its mostly for library writers, not for general programming.
Just like Richard said, you can use friendship. But keep in mind that when you need friendship, you should probably think again about your design. As Richard saids too, maybe putting a as a parameter of A constructor should do exactly what you want.
Here is a working example with friendship :
#include <iostream>
namespace scope
{
class A{
friend class B;
private:
int a;
public:
void print(){
std::cout << a << std::endl;
}
};
class B{
public:
A method(){
A a;
a.a=3;
return a;
}
};
int main(){
scope::B b;
scope::A a = b.method();
a.print(); //just to see it works...
}
Here is a way to do the same without friendship and keeping a private (Ok its ugly :-)
#include <iostream>
namespace scope
{
class B;
class A
{
private:
int a;
public:
void print(){
std::cout << a << std::endl;
}
// A way to only allow B instances to give a correct value
// of "a" member
void pleaseClassBSetMyPrivateMember(B& b);
};
class B
{
public:
A method(){
A a;
a.pleaseClassBSetMyPrivateMember(*this);
return a;
}
int computeValueForMemberOfClassA(A& a){
// you can access public members of a to
// calculate the proper value of a.a member
return 3;
}
};
void A::pleaseClassBSetMyPrivateMember(B& b)
{
// ask for class B object the correct value for member a
a = b.computeValueForMemberOfClassA(*this);
}
};
Related
I was just thinking about it and wondering if it's totally possible, just out of curiosity, as it would be very usefull I think. (but most of my ideas are crazy/insane anyway).
So here it goes:
Is it possible to create a class A, and class B, then add a member to class A by using class B?
Let's suppose we are making a game, or some program in which this would be usefull:
class Player
{
public:
float health;
};
Now, you think of a way to allow extensions by using include files or something:
#define INCLUDE_SPEEDO_METER
#ifdef INCLUDE_SPEEDO_METER
class PlayerSpeedo : public Player
{
public:
float absolute_speed;
//Do some Magic here & there
};
#endif
Now let's suppose we want to access the absolute speed of a player from the Player class like Player.absolute_speed.
Is this possible in any way?
No, that's not possible. You can't "inject" members into another class. Frankly, I can't see why you would ever want to. No one else than you would be aware of this "injected" member.
While you can't syntactically do what you are hoping to do, you can achieve something very close by storing a map in the base class.
class Player
{
public:
Player(float health = 0) { data["health"] = health; }
float health() const { return get("health"); }
float get(std::string const& field) const { return data[field]; }
protected:
std::map<std::string, float> data;
};
class PlayerSpeedo : public Player
{
public:
PlayerSpeedo(float absolute_speed) {data["absolute_speed" = absolute_speed; }
float absolute_speed() const { return get("absolute_speed"); }
};
What you're talking about is not possible in a statically typed language, but it would work in a dynamically typed language (like Python).
A way of achieving that in C++ would be to use a Map between string names of properties and some generic wrapper for property values.
Not quite what you're asking for, but would give you somewhat similar capabilities is the recent proposal for a future version of the C++ standard Call syntax: x.f(y) vs. f(x,y)
This would enable you to write a standalone function float absolute_speed(const Player& p) { return 0.0f; } that you could call via Player p; auto speed = p.absolute_speed() without changing the definition of Player. This is a similar idea to extension methods in C#.
Maybe you like the way which is often done to extend a base class by another class with a template like the following. There is no need for runtime polymorphism which is often a criteria for speed while optimizing can go down to the executed functions without stopping at the virtual functions.
As you can see from the example, it looks like injection of methods and attributes. C++11 offer it to use the constructor from the class which you use to extend the given class very simple. OK, this is a stupied example but maybe it give you an idea how the thing works.
#include <iostream>
class Empty
{
public:
void DoSomething() { std::cout << "Nothing" << std::endl;}
};
class Extender
{
private:
int x;
public:
Extender(int _x):x(_x) {}
void DoSomething() { std::cout << "Value " << x << std::endl; }
};
template <typename ExtendWith>
class User: public ExtendWith
{
public:
using ExtendWith::ExtendWith;
void DoIt() { ExtendWith::DoSomething(); }
};
int main()
{
User<Empty> userEmpty;
userEmpty.DoIt();
User<Extender> userExtended(100);
userExtended.DoIt();
}
I don't think the language could allow what you're trying to do without introducing inconsistencies.
I don't think you want to modify the actual type though, since what you describe is essentially converting a super-type instance into a sub-type instance. You could do this by adding a constructor to the sub-type...
class PlayerSpeedo : public Player {
public:
float absolute_speed;
explcit PlayerSpeedo(const Player& p, float absolute_speed=0, ...) : health(p.health) {
// copy Player values
}
Another option might be storing a reference to the original object, and decorating it. This doesn't alter the type though.
This is a question to find out the better programming practice:
In C++, say I have two classes one of which is a member class of the other, e.g.,
class SomeClass {
public:
MemberClass member_class;
void set_num(double num_) { num_ = num; }
double num() {return num_; }
private:
double num_;
}
I want the member class to have access to the member functions of the outer class, e.g.,
class MemberClass {
public:
PrintSquare() {
cout << num() * num() << endl;
}
}
I am trying to achieve this in order to reduce the number of function arguments I am passing all around the program.
The most common (and IMHO proper) way to solve this problem is, introducing an interface (or even more interfaces focusing on particular sets of method features) for the containing class, and pass that one to the 'inner' class member on construction:
struct Interface {
virtual void set_num(double num_) = 0;
virtual double num() const = 0;
virtual ~Interface() {}
};
class MemberClass {
public:
MemberClass(Interface& interface) : interface_(interface) {}
PrintSquare() {
cout << interface_.num() * interface_.num() << endl;
}
private:
Interface& interface_;
};
class SomeClass : public Interface {
public:
MemberClass member_class;
SomeClass() : member_class(*this), num_() {}
virtual void set_num(double num_) { num_ = num; }
virtual double num() const { return num_; }
virtual SomeClass() {}
private:
double num_;
};
NOTE:
Calling methods of the interface though will fail (with a runtime exception), when called from the MemberClass constructor definition.
Although the answer by Kerrek is very interesting, he himself already states this normally isn't the way to go. Common practice would be to make the inner class nested in the outer one, if possible. If the inner one needs access to the outer one in such a way that a nested connection seems natural, this would be the way to go. Construction of an Inner object would then need a reference to the object it is a member from, in order to be able to call functions on its parent:
class Outer
{
class Inner
{
Outer &parent; // consider constness
public:
Inner(Outer &_parent); //initializes the parent-reference
void innerFunction(); // can call members of parent
};
Inner inner;
public:
Outer(): inner(*this) { ... } // initialize inner
};
Depending on the standard you're using, the innerFunction now has access to all public members of Outer (C++03), or even all private members as well (C++11). See also this topic:
C++ nested classes - inner/outer relationship
EDIT: Did a quick test, and my compiler (gcc 4.7.2) also allows access to private members with older standards. Maybe someone could comment on this...
If your classes are all standard-layout, then you can take advantage of some layout guarantees that C++ makes, namely that a on object of standard layout type may be treated as if it were its own first member. For instance:
struct Foo
{
int a;
void barely_legal();
};
struct Bar
{
Foo x;
int y;
};
#include <type_traits>
void Foo::barely_legal()
{
static_assert(std::is_standard_layout<Foo>::value, "Foo");
static_assert(std::is_standard_layout<Bar>::value, "Bar");
Bar * p = reinterpret_cast<Bar *>(this);
++p->y;
}
This is unusual at best and cruel at worst, so please don't write code like this unless you have a really good reason to do so. (I know people who do have reason to do this, but I don't turn my back towards them.)
Hi I am pretty new to C++ and im converting C code to C++. I started by converting all the structs to classes, and added accessors and mutators for the internals, but some structs have other structs inside them. I want to know the best method for setting the internals of a class within a class, such as
struct1.struct2.struct3.i = 5;
where i is an int. Should I be passing as reference using accessors? but seeing as accessors tend to be const would this be something I should do?
something like
class1.get_class2().get_class3().set_i(5) or something if it can be done in this kind of format.
This is probably a dumb question but i have no idea how to do it, Thank You
class1.get_class2().get_class3().set_i(5)
is possible if get_class2() is non-const and returns a non-const pointer reference.
However, this approach completely breaks the encapsulation. The users of class1 should not (and must not) know that class1 uses class2 inside and that in turn uses class3 inside.
If a setter-API is absolutely necessary, then a better approach is do it hierarchically. For example
// User
class1.set_i( 5 );
// class1
class1::set_i( int x ) { class2_obj.set_i( x ); }
// class2
class2::set_i( int x ) { class3_obj.set_i( x ); }
// class3
class3::set_i( int x ) { i_ = x; }
I am not so sure about that ... did you put a class inside a class or an object inside a class ?
something like :
class OBJ1
{
//methods , and other stuff
}
class OBJ2
{
public OBJ1 *O ;
}
is valid , so you can acces a method like :
OBJ2 *N2 ;
N2->O->some_method();
however , something like
class OBJ2
{
class OBJ1;
}
is not valid :P
again... not sure if this is exactly what you asked ...
If you really have a good reason to access your member object via getters and setters, you can do the following:
class A {
public:
void f() const {}
};
class B {
public:
const A &get_a() const {
// the returned reference will be read-only, i.e. only non-const member
// functions can be called, and public members can not be written.
// it needs to be stored in a const A & object.
return a;
}
A &get_writable_a() {
return a;
}
void set_a(A &a) {
//make sure that the assignment operator of A will take care of all the
//dirty internals, such as internal buffers that need to be deleted.
this->a = a;
}
private:
//the member
A a;
};
int main() {
B b;
b.get_a().f();
}
If you don't have a good reason to do so, I'd recommend to simply make it a public member, and access it directy:
class A {
public:
void f() const {}
};
class B {
public:
A a;
};
int main() {
B b;
b.a.f();
}
Isn't that simply much more elegant?
Note that you can use friend to specify other functions or classes that are allowed to directly access your private members.
As was also pointed out in an other answer, in most cases it is a bad idea to make a member object visible to the outside at all.
This question already has answers here:
Can I access private members from outside the class without using friends?
(27 answers)
Closed 6 years ago.
I have a class A as mentioned below:-
class A{
int iData;
};
I neither want to create member function nor inherit the above class A nor change the specifier of iData.
My doubts:-
How to access iData of an object say obj1 which is an instance of class A?
How to change or manipulate the iData of an object obj1?
Note: Don't use friend.
Here's a way, not recommended though
class Weak {
private:
string name;
public:
void setName(const string& name) {
this->name = name;
}
string getName()const {
return this->name;
}
};
struct Hacker {
string name;
};
int main(int argc, char** argv) {
Weak w;
w.setName("Jon");
cout << w.getName() << endl;
Hacker *hackit = reinterpret_cast<Hacker *>(&w);
hackit->name = "Jack";
cout << w.getName() << endl;
}
Bad idea, don't do it ever - but here it is how it can be done:
int main()
{
A aObj;
int* ptr;
ptr = (int*)&aObj;
// MODIFY!
*ptr = 100;
}
You can't. That member is private, it's not visible outside the class. That's the whole point of the public/protected/private modifiers.
(You could probably use dirty pointer tricks though, but my guess is that you'd enter undefined behavior territory pretty fast.)
EDIT:
Just saw you edited the question to say that you don't want to use friend.
Then the answer is:
NO you can't, atleast not in a portable way approved by the C++ standard.
The later part of the Answer, was previous to the Q edit & I leave it here for benefit of >those who would want to understand a few concepts & not just looking an Answer to the >Question.
If you have members under a Private access specifier then those members are only accessible from within the class. No outside Access is allowed.
An Source Code Example:
class MyClass
{
private:
int c;
public:
void doSomething()
{
c = 10; //Allowed
}
};
int main()
{
MyClass obj;
obj.c = 30; //Not Allowed, gives compiler error
obj.doSomething(); //Allowed
}
A Workaround: friend to rescue
To access the private member, you can declare a function/class as friend of that particular class, and then the member will be accessible inside that function or class object without access specifier check.
Modified Code Sample:
class MyClass
{
private:
int c;
public:
void doSomething()
{
c = 10; //Allowed
}
friend void MytrustedFriend();
};
void MytrustedFriend()
{
MyClass obj;
obj.c = 10; //Allowed
}
int main()
{
MyClass obj;
obj.c = 30; //Not Allowed, gives compiler error
obj.doSomething(); //Allowed
//Call the friend function
MytrustedFriend();
return 0;
}
http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html
this guy's blog shows you how to do it using templates. With some modifications, you can adapt this method to access a private data member, although I found it tricky despite having 10+ years experience.
I wanted to point out like everyone else, that there is an extremely few number of cases where doing this is legitimate. However, I want to point out one: I was writing unit tests for a software suite. A federal regulatory agency requires every single line of code to be exercised and tested, without modifying the original code. Due to (IMHO) poor design, a static constant was in the 'private' section, but I needed to use it in the unit test. So the method seemed to me like the best way to do it.
I'm sure the way could be simplified, and I'm sure there are other ways. I'm not posting this for the OP, since it's been 5 months, but hopefully this will be useful to some future googler.
In C++, almost everything is possible! If you have no way to get private data, then you have to hack. Do it only for testing!
class A {
int iData;
};
int main ()
{
A a;
struct ATwin { int pubData; }; // define a twin class with public members
reinterpret_cast<ATwin*>( &a )->pubData = 42; // set or get value
return 0;
}
There's no legitimate way you can do it.
Start making friends of class A. e.g.
void foo ();
class A{
int iData;
friend void foo ();
};
Edit:
If you can't change class A body then A::iData is not accessible with the given conditions in your question.
iData is a private member of the class. Now, the word private have a very definite meaning, in C++ as well as in real life. It means you can't touch it. It's not a recommendation, it's the law. If you don't change the class declaration, you are not allowed to manipulate that member in any way, shape or form.
It's possible to access the private data of class directly in main and other's function...
here is a small code...
class GIFT
{
int i,j,k;
public:
void Fun()
{
cout<< i<<" "<< j<<" "<< k;
}
};
int main()
{
GIFT *obj=new GIFT(); // the value of i,j,k is 0
int *ptr=(int *)obj;
*ptr=10;
cout<<*ptr; // you also print value of I
ptr++;
*ptr=15;
cout<<*ptr; // you also print value of J
ptr++;
*ptr=20;
cout<<*ptr; // you also print value of K
obj->Fun();
}
friend is your friend.
class A{
friend void foo(A arg);
int iData;
};
void foo(A arg){
// can access a.iData here
}
If you're doing this regularly you should probably reconsider your design though.
access private members outside class ....only for study purpose ....
This program accepts all the below conditions
"I dont want to create member function for above class A. And also i dont want to inherit the above class A. I dont want to change the specifier of iData."
//here member function is used only to input and output the private values ...
//void hack() is defined outside the class...
//GEEK MODE....;)
#include<iostream.h>
#include<conio.h>
class A
{
private :int iData,x;
public: void get() //enter the values
{cout<<"Enter iData : ";
cin>>iData;cout<<"Enter x : ";cin>>x;}
void put() //displaying values
{cout<<endl<<"sum = "<<iData+x;}
};
void hack(); //hacking function
void main()
{A obj;clrscr();
obj.get();obj.put();hack();obj.put();getch();
}
void hack() //hack begins
{int hck,*ptr=&hck;
cout<<endl<<"Enter value of private data (iData or x) : ";
cin>>hck; //enter the value assigned for iData or x
for(int i=0;i<5;i++)
{ptr++;
if(*ptr==hck)
{cout<<"Private data hacked...!!!\nChange the value : ";
cin>>*ptr;cout<<hck<<" Is chaged to : "<<*ptr;
return;}
}cout<<"Sorry value not found.....";
}
I have a class with a protected method Zig::punt() and I only want it to be accessible to the class "Avocado". In C++, you'll normally do this using the "friend Avocado" specifier, but this will cause all of the other variables to become accessible to "Avocado" class; I don't want this because this breaks encapsulation.
Is what I want impossible, or does there already exist an obscure trick out there that I can use to achieve what I want? Or possibly alternative class design patterns that'll achieve the same thing?
Thanks in advance for any ideas!
Here's an ugly yet working trick:
class AvocadoFriender {
protected:
virtual void punt() = 0;
friend class Avocado;
}
class Zig : public AvocadoFriender {
...
protected:
void punt();
}
Basically you add a mixin class that exposes only the part of the interface that you want to Avocado. We take advantage of the fact that by inheriting a class that is befriended to Avocado you don't expose anything more except what was exposed originally.
I personally like the Key pattern.
class WannaBeFriend { /**/ };
class WannaBeFriendKey: boost::noncopyable
{
friend class WannaBeFriend;
WannaBeFriendKey () {}
};
And now:
class LimitedAccess
{
public:
Item& accessItem(const WannaBeFriendKey&) { return mItem; }
private:
Item mItem;
Item mOtherItem;
};
I really like this solution because:
you only need a forward declaration (like for friendship)
you don't have the full access granted by friendship, instead only a limited access is granted, under the full control of the class writer
moreover it's perfectly clear what can be accessed and from whom, thus easing debugging
this access can be granted to child classes of WannaBeFriend: it only needs exposing a protected: static const WannaBeFriend& Key(); (may or may not apply)
And of course, it's very likely that the compiler will optimize the passing of this reference since it does not serve any purpose, so it does not corrupt the design nor add unnecessary temporaries :)
You can add a proxy to the Zig class
class Foo
{
private:
int m_x, m_y;
public:
class Bar
{
friend class Baz;
int& x(Foo& blubb)
{
return blubb.m_x;
}
};
friend class Bar;
};
class Baz
{
public:
void grml(Foo& f)
{
Foo::Bar b;
// Yes, this looks awful
b.x(f) = 42;
}
};
void z()
{
Foo f;
Baz b;
b.grml(f);
}