Good morning everybody, I'm trying to write a member function of a class OUTER_CLASS which returns a unique_ptr to a private class INNER_CLASS defined within the OUTER_CLASS itself. My intent is to write a factory method which returns a reference to an Interface Class which allows to interact with the Implementation Class hided from client. Apart from the design choice, I have a compilation issue: given the following snippet of code, which is a very simplified version of my architecture
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class OuterClass
{
class InnerClass
{
friend class OuterClass;
public:
void myPrint() { cout << "Inner Class " << a << endl;}
InnerClass(int inA) : a(inA) {};
private:
int a;
};
public:
std::unique_ptr<InnerClass> CreateInnerClass()
{
std::unique_ptr<InnerClass> innerObj;
innerObj.reset(new InnerClass(1));
return innerObj;
}
};
int main()
{
OuterClass obj;
std::unique_ptr<OuterClass::InnerClass> innerObj = obj.CreateInnerClass();
innerObj->myPrint();
}
I get following error:
main.cpp: In function 'int main()':
main.cpp:43:10: error: 'class OuterClass::InnerClass' is private within this context
43 | std::unique_ptr<OuterClass::InnerClass> innerObj = obj.CreateInnerClass();
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:20:11: note: declared private here
20 | class InnerClass
| ^~~~~~~~~~
if instead i use AUTO type deduction, writing
int main()
{
OuterClass obj;
auto innerObj = obj.CreateInnerClass();
innerObj->myPrint();
}
everything is fine... How is it possible? What am i doing wrong? Thanks in advance for any answer
Accessibility applies on name, not the type being referred to. So you just can't use the name OuterClass::InnerClass directly in main(), but you can still use the type like calling member functions on the returned object whose type is OuterClass::InnerClass like
obj.CreateInnerClass()->myPrint();
Given auto innerObj = obj.CreateInnerClass(); the name OuterClass::InnerClass is not used directly then it doesn't violate the accessibility check. For the same reason you can use decltype too, even it seems redundant. E.g.
decltype(obj.CreateInnerClass()) innerObj = obj.CreateInnerClass();
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