Access out of scope variables without passing them? - c++

Is there a way to access variables outside their class?
class MyClass1
{
public:
int x;
};
class MyClass2
{
public:
int get_x()
{
//somehow access MyClass1's variable x without
//passing it as an argument and return it.
}
}
int main()
{
MyClass1 obj1;
obj1.x = 5;
MyClass2 obj2;
std::cout << obj2.get_x();
return 0;
}
One of the main things making me reluctant to split my programs into many small organized classes rather than a few messy huge ones is the hassle of passing every single variable that one class might need from another. Being able to access variables without having to pass them (and having to update both declarations and definitions should something change) would be very convenient and would let me code more modually.
Any other solutions to my issue would also be appreciated, as I suspect there may be something dangerous about trying to access variable this way.

The only way you can get access to the x of MyClass1 is if you have an instance of that class, because x is not static.
class MyClass2
{
public:
MyClass2(MyClass1* c1) : myC1(c1) {}
int get_x()
{
return myC1->x;
}
private:
MyClass1* myC1;
}
Then you can use this like
int main()
{
MyClass1 obj1;
obj.x = 5;
MyClass2 obj2{&obj1};
std::cout << obj2.get_x();
return 0;
}

Related

In C++, how to create a global instance of a class (with no parameterless constructor) in the main function?

I have a variable of a user defined type which I declare outside the main function but which I want to instantiate in the main function
Here is my code.
#include <iostream>
class MyClass {
private:
int x;
public:
MyClass(int x) {
this->x = x + 1;
}
int GetX() {
return x;
}
};
MyClass myInstance; // <------ Why not?
void SomeFunction(MyClass a) {
// do stuff with a
}
int ComplicatedFunction() {
// do lots of work
return 5;
}
int main()
{
int x = ComplicatedFunction();
myInstance = MyClass(x); <------ make instance here because need to calculate x first
SomeFunction(myInstance);
}
So I have MyClass myInstance; declared outside of main. And inside main I attempt myInstance = MyClass(x);
The compiler (clang) complains that the global declaration is not allowed because the class does not have a parameterless constructor.
I do not want to use pointers.
I do not want to add a parameterless constructor.
I do not want to instantiate myInstance outside of main.
This is for learning.
How do I get this code to work?
Am I missing some fundamental C++ concept here?
Although I don't recommend it, you technically can achieve this by making your global variable an optional:
std::optional<MyClass> myInstance;
int main()
{
int x = ComplicatedFunction();
myInstance = MyClass(x);
SomeFunction(*myInstance);
}
This satisfies all your requirements. I admit, this isn't a pointer but it behaves very much like it.
The problem is that your class has no constructor like MyClass(). So you either construct it with MyClass myInstance(0); or you add the empty constructor to your class. This means that you cannot do it without either braking at least one of the first three rules that you have imposed. Moreover, in your example, rule 3 is already broken as you are instantiating your class outside of your main function.
class MyClass {
private:
int x;
public:
MyClass() = default; // <-- This is the constructor that you are missing.
MyClass(int x) {
this->x = x + 1;
}
int GetX() {
return x;
}
};
So I have MyClass myInstance; declared outside of main.
It is also defined
I do not want to instantiate myInstance outside of main.
But you do.
You can simply have
// Remove global definition
// MyClass myInstance;
int main()
{
int x = ComplicatedFunction();
MyClass myInstance(x);
SomeFunction(myInstance);
}

Can i manipulate the same element of every object of a class?

e.g:
int main()
{
class exampleClass{
public:
int x;
};
exampleClass one;
exampleClass two;
exampleClass three;
if (exampleClass manipulate_all x == 5)
{
// do something
}
return 0;
}
}
instead of:
int main()
{
class exampleClass{
public:
int x;
};
exampleClass one;
exampleClass two;
exampleClass three;
if (one.x == 5)||(two.x == 5)||(three.x == 5)
{
// do something
}
return 0;
}
Very new to c++, so apologies if this is a stupid question, or if this is far too advanced for a beginner.
I'm trying to create a collision system for my game, where each sprite has a class object, so I can check the player object against every other sprite. If this is a terrible idea please tell me.
If you want to have all members share a variable, you can use static variables
If they're part of a collision system you probably need a larger structure to hold all of the variables and just use a loop over that.
Alternatively, you could have a static variable as a list keep track of all other members of the class and loop over this, where the static variable is a vector of pointers to instantiated objects. This requires a lot more overhead for the individual class and its own function to modify all of the values.
Either way you'd have to write the container to hold all the values, but it's up to you on how you want to design it.
Modifying your class:
class exampleClass{
private:
static vector<exampleClass*> instances;
public:
exampleClass(){ instances.push_back(this);}
~exampleClass(){ /*Use some kind of id to find and erase the current instance from the list here.*/}
int x;
};
You can, if your member is a static member, but not if it's an instance member, like your case. But you also need to initialize a static member outside the class.
#include<iostream>
class exampleClass
{
public:
static int x;
};
int exampleClass::x = 0;
int main()
{
exampleClass one;
exampleClass two;
exampleClass three;
exampleClass::x = 5;
std::cout << one.x << two.x << three.x << std::endl;
return 0;
}

Private static class members

When we declare a member variable static, it is shared between all instances of the class. I've heard that you should think of the variable belonging to the class itself, not any instance. This lets us initialize the variable without instantiating any object of the class, which makes sense.
class Something
{
public:
static int s_nValue;
};
int Something::s_nValue = 1;
But why are we allowed to initialize a private static member?
class Something
{
private:
static int s_nValue;
};
int Something::s_nValue = 1;
Does private even mean anything when we are talking about static members?
Yes, it does mean something. Consider the following example, which throws a compiler error, because the member is private. Being able to initialize a private variable is not the same as being able to change it from any context.
class Something
{
private:
static int s_nValue;
};
int Something::s_nValue = 1;
int main(){
Something::s_nValue = 2; // Compiler error here.
}
Private still means the same thing: you cannot use the name Something::s_nValue except in the definition of a member of Something (or a friend, or a nested class within Something).
int Something::s_nValue = 1;
is the definition of a member of Something - namely, that static member s_nValue.
int Something::another_static_val = s_nValue; // also okay
int OtherClass::x = Something::s_nValue; // Illegal access!
int Something::getValue() const {
return s_nValue; // okay, getValue is a member of same class
}
int regularFunction() {
return Something::s_nValue; // Illegal access!
}
Does private even mean anything when we are talking about static members?
I'll try to answer with a classic example. Consider the following piece of code:
#include <iostream>
class foo {
static int count;
int id;
public:
foo() : id(++count) {}
int getid() const { return id; }
};
int foo::count = 0;
int main() {
foo f1, f2, f3;
std::cout << f1.getid() << std::endl;
std::cout << f2.getid() << std::endl;
std::cout << f3.getid() << std::endl;
}
LIVE DEMO
In the example above we use a private static int to count the instances of foo created. We made the count static member variable private because we don't want anyone else except object of type foo to mess with it.
And this is only a naive example, think of the possibilities.
Public, private and protected are properties of a class and not of an object. Their purpose is to let you specify which parts of this class are visible to other classes, and not to hide stuff from objects of the same class. So, you can write code like this :
class A
{
public:
bool operator<(const A& other)
{
return this->val < other.val;
}
private:
int val;
};
So, private makes sense even when applied to static members - it just says that other classes cannot see this member.

how to set internals of a class

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.

How to access private data members outside the class without making "friend"s? [duplicate]

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.....";
}