I have been playing around with inner classes in C++
, and I'm bit confused right now.
#include <iostream>
class outer{
private:
class inner{
private:
int something;
public:
void print(){
std::cout<< "i am inner"<<std::endl;
}
};
public:
inner returnInner(){
inner i;
return i;
}
};
int main(){
outer o;
//outer::inner i = o.returnInner(); (1)
//auto i = o.returnInner(); (2)
//i.print();
o.returnInner().print(); //(3)
return 0;
}
This is compiled on Linux with clang++-3.5
and -std=c++14
.
In (1) I'm getting a compiler error as expected because inner
is a private inner class of outer
.
However, in (2) when the auto
keyword is used, compilation is successful and the program runs.
Everything works for (3), too.
Why is this so? Can I prevent returning an instance of private inner class from outer methods while retaining the ability to move and/or copy them within the outer class?
Shouldn't the compiler elicit an error in (2) and (3) like it does in (1)?
why is it so Shouldn't compiler return error in (2) and (3) as in (1)?
It is an interesting question.. and answer to this is even more interesting.
In the code you posted, inner
is a name of a type. It is the name which is declared to be private
, not the type itself1 — accessibility of type doesn't make sense in the context of C++; accessibilty applies to name only — be it name of type, name of function, name of data . So when you hear something like "the type X is a public class", it almost always means "the name X is declared to be public, and it refers to a type and the type is omnipresent, it exists everywhere".
Coming back to why using auto
doesn't give error, well because when you use auto
, you're accessing the type without using its name, which is why it doesn't give error.
how can i prevent return of an instance of private inner class from outer methods,
There is no way.
1. struct { int data; }
is a type, without a name to refer to, though note that is not a valid declaration, because it lacks name. Either you've to declare an object of unnamed type as in struct { int data; } obj;
Or give it a name as struct data_type { int data; };
I'm not sure that it's what you want but you can delete the copy constructor like that:
inner(inner const&) = delete;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With