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.
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.
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.
Say I have an incredibly contrived class defined as follows:
class Outer {
public:
struct Inner {
Inner(int innerValue) : foo(innerValue) {};
int foo;
};
Outer(int innerValue) : _inner(innerValue) {};
const Inner& getInner() const {
return _inner;
};
private:
Inner _inner;
};
I want Outer to be the only class capable of constructing an instance of Inner, but in such a way that other classes/functions can access _inner.foo when passed a reference to _inner through Outer::getInner(). Is this possible? Is there a better way of achieving equivalent functionality?
I'm aware of two solutions to such a problem which I'd like to demonstrate and compare.
Solution 1 (friend):
Using the friend keyword, you can allow another class to access your private functions. (Use carefully.)
You can make the constructor of Inner private, but make Outer a friend of Inner. Note that not only the constructor but any private method of Inner can be called by Outer.
class Outer {
public:
class Inner {
friend class Outer; // <<---- friend
// private to Inner but also callable by Outer (because it's a friend):
Inner(int innerValue) : foo(innerValue) {};
public:
// (add public methods here)
int foo;
};
Outer(int innerValue) : _inner(innerValue) {};
const Inner& getInner() const {
return _inner;
};
private:
Inner _inner;
};
Solution 2 (access keys):
A different approach without friend but slightly more complex is to give the constructor a parameter which only Outer is able to construct (like a "key"). The constructor is then public, but other classes will not be able to call it since they can't provide the arguments required to do so:
class Outer {
// Our dummy struct which is only constructible by Outer:
struct ConstructInnerKey {
// Empty
};
public:
struct Inner {
Inner(int innerValue, Outer::ConstructInnerKey) : foo(innerValue) {};
// ^^^^^^^^^^^^^^^^^^^^^^^^
// a key is required (but not used)
// to construct an instance of Inner
// (add public methods here)
int foo;
};
Outer(int innerValue) : _inner(innerValue, Outer::ConstructInnerKey()) {};
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// make a key and pass it to Inner
const Inner& getInner() const {
return _inner;
};
private:
Inner _inner;
};
Note that while this looks like it adds a performance overhead, this is not the case. Everything is optimized away and only serves for catching access violations during compilation as you'd like to.
Comparison:
Solution 2 has the advantage that Inner only grants Outer to access the constructor. So as long as you want to have "truly" private functions in Inner (not even accessible by Outer), this is a good solution. But solution 1 is a lot easier to write and understand (quick and dirty, so to speak).
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();
}