Hi i need help with this little example.
I am unable to use _test from the nested class
class random
{
public:
int _test;
class nestedClass
{
public:
void notify() override {
_test = 123;
}
} _nestedClass;
};
You can use/pass a pointer to the outer class named random to achieve what you want as follows:
void notify(random* p)
{
p->_test = 123;
}
This is because a nested class can access a non-static member of the enclosing class through a pointer to the enclosing class.
You can also pass arguments as:
void notify(random* p, int i)
{
p->_test = i;
}
You can't access the non-static member of random without a instance of random. You need to tell your nestedClass which _test it want to access. There may be many instances of random out there, and therefor, many _tests.
I think what you want is:
class random
{
public:
int _test;
class nestedClass
{
random& outer_;
public:
nestedClass(random& outer): outer_(outer) {
}
void notify() {
outer_._test = 123;
}
} _nestedClass;
random(): _nestedClass(*this) {
}
};
Related
I'm trying to write a unittest but I'm running into some problems.
I've got a class which has an int to keep track of the current state. All classes that are inherited of this class can change the state by calling the protectedFunction.
class RandomClass
{
public:
RandomClass()
{
mState = 0;
}
protected:
void protectedFunction()
{
++mState;
}
private:
int mState;
friend void UNITTEST_setMState(int state);
friend int UNITTEST_getMState();
};
Now i'd like to write a unittest for this class. So I created a new class which inherits the previous class. To Properly test all the states I need to set the state, and I need to get the state to assert it. I've tried using a friend function but it does not seem to work.
class UnittestRandomClass : public RandomClass
{
public:
void wrapperProtectedFunction()
{
protectedFunction();
}
void UNITTEST_setMState(int state)
{
this->mState = state; // Apparently not like this
}
int UNITTEST_getMState()
{
return this->mState; // Apparently not like this
}
};
int main() {
UnittestRandomClass ut;
ut.UNITTEST_setMState(1);
ut.wrapperProtectedFunction();
int res = ut.UNITTEST_getMState();
ASSERT_EQ(res, 2);
}
I seem to be doing something wrong, as the mState still appears to be private and thus I'm getting an inaccessible error. I've also tried calling it directly by just returning mState, but the same error applies.
One solution would be to move the mState to protected, but as there are other classes which inherit the RandomClass, I do not think that would be a save solution.
So how would I be able to solve such an issue and resolve my errors?
For future viewers here is the working code:
class RandomClass
{
public:
RandomClass()
{
mState = 0;
}
void publicFunction();
protected:
void protectedFunction()
{
++mState;
}
private:
int mState;
friend class UnittestRandomClass;
};
class UnittestRandomClass : public RandomClass
{
public:
void wrapperProtectedFunction()
{
protectedFunction();
}
void setMState(int state)
{
mState = state;
}
int getMState()
{
return mState;
}
};
int main() {
UnittestRandomClass ut;
ut.setMState(1);
ut.wrapperProtectedFunction();
int res = ut.getMState();
ASSERT_EQ(res, 2);
}
Your class declares a free-standing function to be friend.
Your unit test uses a member function of a class, the class is not declared friend.
You can write friend class UnitTestRandomClass;
Specifically, what you want to do, make a member function of a future derived class a friend is not provided by the standard. There is no syntax for that.
I am not sure is my question is right or not? But let me still try to ask once.
I have a Class with have few member variables defined. As per OO concepts, every member function can access , all member variables of its class.
But I want these member variable to be accessed via specific methods (Lets say Getters) , even within same class member functions.
It there any way to do it?
class A {
public:
void func1();
void func2();
B getB();
private:
B b;
}
void A::func1() {
b.functionFromB(); // function uses member variable b directly
}
void A::func2() {
B b1=getB(); // function ask for B from a function and then uses it. // I need something like this... And ensure each function uses same way otherwise there should be warning...
b1.functionFromB();
}
Thanks,
Kailas
No, there is not. You can do it via encapsulation and inheritance like:
class shape
{
private:
int angles;
protected:
shape(int angles_):angles(angles_){};
int getAngles() const;
}
class square : private shape
{
public:
square():shape(4){}
void doSth()
{
\\ you can access angles only via getAngles();
}
}
Any private members of the class can be accessed from within the class, but not by users of the class. So it looks like you need private members and public methods that allow access to them.
class A
{
private:
int a;
public:
int getA() {return a;}
};
int main()
{
A inst;
int t;
inst.a =5; // error member a is private
t = inst.getA(); //OK
}
The concept extends fine to nested class declarations in case you only want to allow instance of a class to be created from another class; details here
As others have said - you have to add an additional layer.
If you want to give access to specific methods then you can use the friend keyword. E.g.
// Public.h
#pragma once
class Public
{
public:
Public();
int GetI() const;
float GetF() const;
private:
std::unique_ptr<Private> p_;
};
//Public.cpp
#include "Public.h"
Public::Public()
: p_(new Private)
{
}
int Public::GetI() const
{
return p_->i_;
}
float Public::GetF() const
{
return p_->f_;
}
// Private.h
#pragma once
class Private
{
friend int Public::GetI() const;
friend float Public::GetF() const;
int i_;
float f_;
};
Keep in mind that every friend method can access ALL private members.
If you really really want to limit which methods can access which members then you can wrap each member in a separate class/struct and make only the getter/setter of that member a friend of that class/struct but I would not recommend this approach.
Here is what I'm trying to accomplish:
-Client registers a function (fun) with the class (foo)
-Fun has a general form type function(int, int,int)
-Foo then, in executing its work, calls that function which may require access to private members.
The point is to allow user defined functions which Foo can use in the course of its work. Is there a pattern/nuance of C++ etc.. that would make this feasible?
Worst case scenario I can make the data public but I'm curious if something better exists.
TIA
Example:
class foo;
typedef float (*client_fun)(foo &obj, int &i);
class foo
{
client_fun their_fun;
int private_info;
public:
foo(): private_info(42){};
void set_fun(client_fun _fun)
{
their_fun = _fun;
}
float run_foo()
{
//Oversimplified example of what it would be doing.
//their_fun would be called as part of a complicated method
int i;
i = 1;
return their_fun(*this, i);
}
};
float fancy_fun(foo &obj, int &i)
{
//needs access to private info
return (i/obj.private_info);
}
int main()
{
//Hypothetical use
foo my_foo;
my_foo.set_fun(fancy_fun);
//Can't access the private member
my_foo.run_foo();
return 0;
}
G++ example.cpp:
example.cpp: In function ‘float fancy_fun(foo&, int&)’:
example.cpp:8:8: error: ‘int foo::private_info’ is private
int private_info;
^
example.cpp:32:18: error: within this context
return (i/obj.private_info);
This is the pattern that answers my question.
#include <iostream>
class engine;
class settings
{
//Can friend the engine class if we have private members we want to be able to call
friend class engine;
public:
int private_info;
settings()
{
private_info = 42;
};
};
typedef float (*fn_ptr)(settings &);
class engine
{
//private info will still be private to the world since the engine owns the settings object
settings my_settings;
fn_ptr my_fn;
public:
engine(): my_settings(){};
void set_fun(fn_ptr _ptr)
{
my_fn = _ptr;
}
void run()
{
std::cout << my_fn(my_settings, 1) << "\n";
}
};
float fancy_fun(settings &obj, size_t i)
{
//needs access to private info
return (obj.private_info);
}
int main()
{
//Hypothetical use
engine my_engine;
my_engine.set_fun(fancy_fun);
//Error! Private!
//my_engine.my_settings;
/*Is now accessing the public member of a private object
* using an appropriately specified user function */
my_engine.run();
return 0;
}
Is it possible in c++ to access class variables in other classes without creating an object. I have tried to use static, but the other class doesnt recognize my variable.
I have 3 classes. In two of those the sae variables should be used. In the third class I am changing the values. Would be grateful if you could help. Maybe youve got an example.
class Myclass
{
public:
static int i;
};
int Myclass::i = 10;
class YourClass
{
public:
void doSomething()
{
Myclass::i = 10; //This is how you access static member variables
}
};
int main()
{
YourClass obj;
obj.doSomething();
return 0;
}
static is the right keyword here:
class A {
public:
static int i; // <-- this is a class variable
};
class B {
public:
void f() { A::i = 3; } // <-- this is how you access class variables
};
They only potential problem I can think of is that
You made the class variable protected or private, thus rendering it inaccessible from other code.
You forgot to specify the full scope of the class variable (with A:: in this example).
I think the Singleton Pattern would help, but I'm no big fan of it. A lot better design would be to have one class take ownership of the object, and pass references to this object to the other classes.
yes you can bro, try this
struct car{
string model;
string paint;
int price;
};
int main(){
// creates an object of the class car
car BMW;
// assign the values
bmw.model = "m sports";
bmw.paint ="red";
bmw.price = 24000;
}
class Outer {
class Inner {
public:
Inner() {}
void func() ;
};
private:
static const char* const MYCONST;
int var;
};
void Outer::Inner::func() {
var = 1;
}
const char* const Outer::MYCONST = "myconst";
This errors out when I compile with class Outer::Inner' has no member named `var'
An inner class is a friend of the class it is defined within.
So, yes; an object of type Outer::Inner can access the member variable var of an object of type Outer.
Unlike Java though, there is no correlation between an object of type Outer::Inner and an object of the parent class. You have to make the parent child relationship manually.
#include <string>
#include <iostream>
class Outer
{
class Inner
{
public:
Inner(Outer& x): parent(x) {}
void func()
{
std::string a = "myconst1";
std::cout << parent.var << std::endl;
if (a == MYCONST)
{ std::cout << "string same" << std::endl;
}
else
{ std::cout << "string not same" << std::endl;
}
}
private:
Outer& parent;
};
public:
Outer()
:i(*this)
,var(4)
{}
Outer(Outer& other)
:i(other)
,var(22)
{}
void func()
{
i.func();
}
private:
static const char* const MYCONST;
Inner i;
int var;
};
const char* const Outer::MYCONST = "myconst";
int main()
{
Outer o1;
Outer o2(o1);
o1.func();
o2.func();
}
An inner class has access to all members of the outer class, but it does not have an implicit reference to a parent class instance (unlike some weirdness with Java). So if you pass a reference to the outer class to the inner class, it can reference anything in the outer class instance.
Anything that is part of Outer should have access to all of Outer's members, public or private.
Edit: your compiler is correct, var is not a member of Inner. But if you have a reference or pointer to an instance of Outer, it could access that.
First of all, you are trying to access non-static member var outside the class which is not allowed in C++.
Mark's answer is correct.
Anything that is part of Outer should have access to all of Outer's members, public or private.
So you can do two things, either declare var as static or use a reference of an instance of the outer class to access 'var' (because a friend class or function also needs reference to access private data).
Static var
Change var to static If you don't want var to be associated with the instances of the class.
#include <iostream>
class Outer {
private:
static const char* const MYCONST;
static int var;
public:
class Inner {
public:
Inner() {
Outer::var = 1;
}
void func() ;
};
};
int Outer::var = 0;
void Outer::Inner::func() {
std::cout << "var: "<< Outer::var;
}
int main() {
Outer outer;
Outer::Inner inner;
inner.func();
}
Output- var: 1
Non-static var
An object's reference is a must to access any non-static member variables.
#include <iostream>
class Outer {
private:
static const char* const MYCONST;
int var;
public:
class Inner {
public:
Inner(Outer &outer) {
outer.var = 1;
}
void func(const Outer &outer) ;
};
};
void Outer::Inner::func(const Outer &outer) {
std::cout << "var: "<< outer.var;
}
int main() {
Outer outer;
Outer::Inner inner(outer);
inner.func(outer);
}
Output- var: 1
Edit - External links are links to my Blog.
var is not a member of inner class.
To access var, a pointer or reference to an outer class instance should be used. e.g. pOuter->var will work if the inner class is a friend of outer, or, var is public, if one follows C++ standard strictly.
Some compilers treat inner classes as the friend of the outer, but some may not. See this document for IBM compiler:
"A nested class is declared within the scope of another class. The name of a nested class is local to its enclosing class. Unless you use explicit pointers, references, or object names, declarations in a nested class can only use visible constructs, including type names, static members, and enumerators from the enclosing class and global variables.
Member functions of a nested class follow regular access rules and have no special access privileges to members of their enclosing classes. Member functions of the enclosing class have no special access to members of a nested class."