I would like to declare an instance of my class outer, then use that to declare an instance of outer's child class inner. In the project I'm working on, I would like to be able to declare several instances of an inner class, using different constructors. These instantiations should be able to access the private variables in outer. This example is a simplification of my problem. Can someone tell me what I'm doing wrong, or post a working example?
using namespace std;
#include <iostream>
class outer
{
private:
int x;
public:
outer(int input){x=input;};
class inner
{
public:
int showx(){cout<<outinst->x<<"\n";};
};
};
int main()
{
cout<<"hello julian\n";
outer* clevername(5);
//I can't make it work past this point. The desired efect is
//to declare an instance of outer initiated with a value of x,
//use this instance of outer to declare an instance of inner,
//then use this instance of inner to return the original value of x
clevername->inner* ins;
cout<<ins->showx()<<"\n";
};
The nested class (inner) is not automatically a data member of outer nor does an object of type outer::inner have any access to any private members of any object of type outer. Moreover, to access members of an object you need the . operator. Finally, you're confusing objects with pointers.
Here is an attempt at a code that does perhaps what you intended (not tried it so it may still need debugging).
#include <iostream>
class outer
{
const int x;
public:
outer(int input) : x(input) {}
class inner;
friend class inner; // inner must be friend to access private member x
class inner
{
const outer* const outinst; // const pointer to an outer object
public:
inner(const outer*out) : outinst(out) {}
int showx() const
{ return outinst->x; }
};
};
int main()
{
std::cout<<"hello julian\n";
outer clevername(5); // declare object of type outer
outer::inner ins(&clevername); // declare object of type outer::inner
std::cout << ins.showx() << "\n";
};
Note that there is no benefit or other use of the fact that outer::inner is a member type of outer, i.e. the same effect could have been achieved (more easily) by declaring inner as another freestanding class.
This
clevername->inner* ins;
is wrong. Use
outer::inner ins;
instead. BTW you have also incorrect clevername declaration, it does not declare an object but a pointer. Do not use pointers unless you know what you are doing.
Related
I have a class inside a class.
The outer class does some processing to generate an array of values.
I want the inner class to be able to access the outer class' array.
Is there a clean way to achieve this?
I'm thinking to have a method in the outer class that calls a method in the inner class sending him the address of the array and the inner class needs to hold a pointer in its private member section in order to later point to it by assignment from the method that receives the address. But this feels a little clunky.
Upon construction you can pass a reference of outer class to the constructor of the inner class. Using the reference you can call any function of the outer class.
// The actual definition of the inner class.
class inner {
public:
inner(outer& o) : outer_(o) // Set the reference.
{
}
// The function using the data in outer.
void do_stuff()
{
int x = outer_.get_data() + 5;
}
private:
// A reference to the outer class.
outer& outer_;
}
// The actual outer class.
class outer {
public:
outer() : inner_(*this) // Set the reference using the this object.
{
}
// This is the function you would like to call.
int get_data();
private:
inner inner_;
}
C++ has a concept of the nested class. A nested class, which is declared in another enclosing class. It is a member and has the same access rights as any other member of the enclosing class. But the members of an enclosing class have no special access to members of a nested class.you can refer to this sample code. Hope this will help
class Outer {
private:
int arry[];
class inner {
private:
int innerArr[];
void Fun(Outer *e) {
innerArr = e->arry;
}
};
};
int main(){
Outer out;
Outer::inner in;
in.Fun(out);
}
Okay, here it is in full. Key points:
C++ has nested classes, however that's a 100% compile-time thing dealing with scoping and encapsulation, the class instances are 100% independent.
Therefore if you want either class to use the other in any way, it must either create an instance or accept one.
(and then, given an outer instance, the inner class is allowed to access its private parts that's the only thing that actually differs from normal scoping).
So knowing that, here is a concrete example.
→ Outer owns a vector of Inners.
→ Inner needs to use its owning Outer instance
➥ say Outer could be some kind of List and Inner some kind of Item
class Outer
{
public: // can be private, in which case Inner won't be usable from outside
class Inner
{
Outer & m_outer;
public:
Inner(Outer & outer) : m_outer(outer) {}
void doOuterMagic() { m_outer.doMagic(); }
};
public:
void addInner() { m_inners.emplace_back(*this); }
private: // could be public, but I want to illustrate Inner access to private members
void doMagic() { std::cout <<"magic"; }
private:
std::vector<Inner> m_inners;
};
As with any class, you may also define it below the outer class if it's more readable. You'd do it like this:
class Outer
{
public: // can be private, in which case Inner won't be usable from outside
class Inner;
public:
// ... unchanged ...
};
class Outer::Inner // note the scoping here
{
// ... exactly what was in class Inner above
};
Notes:
Any relationship Outer and Inner have it up to your design, C++ assumes none.
If Outer works in close relationship with Inner, it's pretty common to have Outer create Inner instances and pass itself to them, as I did in addInner here.
I made m_outer a reference, but this prevents Inner from satisfying *Assignable requirements. If you need the class to satisfy those, make it a pointer instead.
Hello I am wondering why C++ standard allows us in nested classes to access outer class's private fields, while it forbids to access inner class's private fields from the outer class. I understand, that this example:
class OuterClass{
public:
class InnerClass{
public:
void printOuterClass(OuterClass& outer) {cout << outer.m_dataToDisplay;};
};
private:
int m_dataToDisplay;
};
is fine, because thing, that Inner class sometimes can be complicated. But I think following scenario is also fine:
class Algorithm{
public:
class AlgorithmResults{
public:
void readAlgorithmResult();
private:
void writeAlgorithmResult();
};
void calculate(AlgorithmResults& results, Arguments...){
//calculate stuff
results.writeAlgorithmResult(results);
}
};
For me this structure makes perfect sense, although it is not allowed in C++. I also noticed, that for some time both were allowed in Java, but now second example is also forbidden.
What is the reason, that first example is allowed and another is denied?
Essentially, within a scope names declared earlier in that scope are valid and can be used directly (unless they're shadowed). Code outside a scope can't directly use names declared inside the scope. E.g. code after a curly braces block, can't directly use variables declared inside that block (an example of indirect use is when the outside code has access to a pointer to a static variable inside the curly braces block).
For the second example, just make Algorithm a friend of AlgorithmResults:
class AlgorithmResults
{
friend class Algorithm;
The nested classes could access outer class's private fields, because it's a member of the outer class, just same as the other members.
[class.access.nest]/1
A nested class is a member and as such has the same access rights as any other member.
On the other hand, the outer class doesn't have special access rights on the nested class, they're just normal relationship.
The members of an enclosing class have no special access to members of a nested class; the usual access rules ([class.access]) shall be obeyed. [ Example:
class E {
int x;
class B { };
class I {
B b; // OK: E::I can access E::B
int y;
void f(E* p, int i) {
p->x = i; // OK: E::I can access E::x
}
};
int g(I* p) {
return p->y; // error: I::y is private
}
};
— end example ]
Counter question: Why would you want to allow it?
If you need an outer class have access to an inner class' private internals, you can befriend:
class Foo {
public:
class Frob {
friend class Foo;
int privateDataMember;
};
Foo () {
Frob frob;
frob.privateDataMember = 3735928559;
}
};
C++ has no device to unfriend, so allowing default private access to an outer class would steal you a class design tool and yield reduced default encapsulation.
For a code like this:
class foo {
protected:
int a;
public:
class bar {
public:
int getA() {return a;} // ERROR
};
foo()
: a (p->param)
};
I get this error:
invalid use of non-static data member 'foo::a'
currently the variable a is initialized in the constructor of foo.
if I make it static, then it says:
error: 'int foo::a' is a static data member; it can only be initialized at its definition
However I want to pass a value to a in the constructor.
What is the solution then?
In C++, unlike (say) Java, an instance of a nested class doesn't intrinsically belong to any instance of the enclosing class. So bar::getA doesn't have any specific instance of foo whose a it can be returning. I'm guessing that what you want is something like:
class bar {
private:
foo * const owner;
public:
bar(foo & owner) : owner(&owner) { }
int getA() {return owner->a;}
};
But even for this you may have to make some changes, because in versions of C++ before C++11, unlike (again, say) Java, a nested class has no special access to its enclosing class, so it can't see the protected member a. This will depend on your compiler version. (Hat-tip to Ken Wayne VanderLinde for pointing out that C++11 has changed this.)
In C++, nested classes are not connected to any instance of the outer class. If you want bar to access non-static members of foo, then bar needs to have access to an instance of foo. Maybe something like:
class bar {
public:
int getA(foo & f ) {return foo.a;}
};
Or maybe
class bar {
private:
foo & f;
public:
bar(foo & g)
: f(g)
{
}
int getA() { return f.a; }
};
In any case, you need to explicitly make sure you have access to an instance of foo.
The nested class doesn't know about the outer class, and protected doesn't help. You'll have to pass some actual reference to objects of the nested class type. You could store a foo*, but perhaps a reference to the integer is enough:
class Outer
{
int n;
public:
class Inner
{
int & a;
public:
Inner(int & b) : a(b) { }
int & get() { return a; }
};
// ... for example:
Inner inn;
Outer() : inn(n) { }
};
Now you can instantiate inner classes like Inner i(n); and call i.get().
You try to access private member of one class from another. The fact that bar-class is declared within foo-class means that bar in visible only inside foo class, but that is still other class.
And what is p->param?
Actually, it isn't clear what do you want to do
Your Question is not clear but there is use case when you will get this issue .
Invalid use of non-static data member.
When you are using "non-static data member in another class try to not use with scope resolution operator
Example::className::memberData = assignivalue ;
instead of above try to use object of className class;
Example:: m_pClassName->memberData=assignValue;*
I have
class outer: public base
{
public:
class inner
{
foo();
}
}
How do i initialize these nested class?
Can I call foo() from the outer class?
Can you please tell me what is the thumb rule I should know while nesting class and accessing the members?
Thank you
I guess you're coming from java.
A c++ nested struct/class is like a java static nested type. It has no instance-relation with the containing type.
In fact you should be able to move the inner class to the containing namespace with no other changes than the potential need to mark the former inner class as a friend of the outer class.
See for demonstration http://ideone.com/ddjGX
How do i initialize these nested class?
You don't. You can only initialize members (class instances)
Can I call foo() from the outer class?
Not unless you are a friend or the method (foo()) is public
Can you please tell me what is the thumb rule I should know while nesting class and accessing the members?
I'd choose a nested type only if
the type is an implementation detail or depends on the outer class
the convenience of sharing static members (enums, typedefs, template arguments, static methods and fields) from the outer class: the inner class is implicitly a friend of the outer class.
I illustrated these 'rules of thumb' below. Note how the nested type has transparent access to private members of the outer class.
struct base {};
class outer: public base
{
private:
enum { some=42, special=67, implementation=999, details=-13 };
public:
struct inner
{
protected:
void foo() { int can_usethis = special + implementation + details; }
};
outer() : _inner() { }
void call_inner(inner& i) const
{
//i.foo(); // fails (protected)
}
void call_inner() const
{
//_inner.foo(); // fails (protected)
}
private:
inner _inner;
};
int main()
{
outer o;
outer::inner i;
// i.foo(); // fails: protected
o.call_inner(i);
}
You can instance inner object using scope operator :: (outer::inner()) . If you want to acceess foo() from outer class you maybe want to define outer like friend class of inner.
HI,
In C++ inner class,
class A {
public:
void f1();
private:
void f2();
class B {
private void f3();
};
}
Does an inner class (B) has a pointer to its parent class (A)? (like it does in Java).
And can B calls its parent class public/private method (like it does in Java).
Thank you.
No -- in C++, nesting classes only affects names and visibility, not the semantics of the class itself. As far as generated code goes, the nested class is no different from one that isn't nested.
All that's changed is the visibility and the name (e.g. if it's in a private: section of the outer class, it's not visible to the outside world, and if it's in a public: section, it's visible, but (of course) to name it you use outer_class::inner_class. It's still a completely separate class though -- just for example, you can create an instance of the inner class without creating any instance of the outer class.
Edit: Sorry, I missed part of your question. In C++ 0x, the inner class does have access to the the private parts of the outer class -- in essence, it's as if the outer class has declared the inner class as its friend, so private names are visible, but you still need to pass it something like a reference to an object of the outer class before it can invoke any non-static member functions of the outer class.
Although this isn't supposed to be the case yet, I believe most compilers implement this particular part already.
No, Class B does not have a pointer to Class A, unless you explicitly add it.
Does it have a pointer to the parent: No.
Does it have access to the parents private members: Sort of
I think the if it has access is not well defined in the standard I could be wrong.
But you can access it in g++
#include <iostream>
class X
{
class Y
{
public:
Y(X* p)
:parent(p)
{}
void TryY()
{
// Access a private member of X
++(parent->value);
}
private:
X* parent;
};
public:
X()
:y(this)
{
value = 4;
}
void TryY()
{
y.TryY();
std::cout << value << std::endl;
}
private:
Y y;
int value;
};
int main()
{
X x;
x.TryY();
}