#include <iostream>
// A factory class that will not call anything except constructor. Even if it could.
template<typename T> class HonestFactory
{
// A factory class that would like to mess with private methods. But it can't.
friend class HeinousFactory;
// This will ensure only Heinous one can use it.
HonestFactory() { }
// Real one should be a variadic template.
T Create()
{
return T{};
}
};
class Foo
{
friend class HonestFactory<Foo>; // We trust the honest one.
Foo() { }
int m_foo {0};
public:
int m_bar {1};
};
class HeinousFactory
{
public:
Foo CreateFoo()
{
HonestFactory<Foo> factory;
Foo foo = factory.Create();
//foo.m_foo = 1; // Error.
foo.m_bar = 1;
return foo;
}
};
int main()
{
//Foo foo1; // No.
//HonestFactory<Foo> factory; // Nope.
HeinousFactory factory;
Foo foo2 = factory.CreateFoo();
std::cout << foo2.m_bar << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKLy8gQSBmYWN0b3J5IGNsYXNzIHRoYXQgd2lsbCBub3QgY2FsbCBhbnl0aGluZyBleGNlcHQgY29uc3RydWN0b3IuIEV2ZW4gaWYgaXQgY291bGQuCnRlbXBsYXRlPHR5cGVuYW1lIFQ+IGNsYXNzIEhvbmVzdEZhY3RvcnkKewoJLy8gQSBmYWN0b3J5IGNsYXNzIHRoYXQgd291bGQgbGlrZSB0byBtZXNzIHdpdGggcHJpdmF0ZSBtZXRob2RzLiBCdXQgaXQgY2FuJ3QuCglmcmllbmQgY2xhc3MgSGVpbm91c0ZhY3Rvcnk7CgkKCS8vIFRoaXMgd2lsbCBlbnN1cmUgb25seSBIZWlub3VzIG9uZSBjYW4gdXNlIGl0LgoJSG9uZXN0RmFjdG9yeSgpIHsgfQoJCgkvLyBSZWFsIG9uZSBzaG91bGQgYmUgYSB2YXJpYWRpYyB0ZW1wbGF0ZS4KCVQgQ3JlYXRlKCkKCXsKCQlyZXR1cm4gVHt9OwoJfQp9OwoKY2xhc3MgRm9vCnsKCWZyaWVuZCBjbGFzcyBIb25lc3RGYWN0b3J5PEZvbz47IC8vIFdlIHRydXN0IHRoZSBob25lc3Qgb25lLgoJRm9vKCkgeyB9CglpbnQgbV9mb28gezB9OwoJCnB1YmxpYzoKCWludCBtX2JhciB7MX07Cn07CgpjbGFzcyBIZWlub3VzRmFjdG9yeQp7CnB1YmxpYzoKCUZvbyBDcmVhdGVGb28oKQoJewoJCUhvbmVzdEZhY3Rvcnk8Rm9vPiBmYWN0b3J5OwoJCUZvbyBmb28gPSBmYWN0b3J5LkNyZWF0ZSgpOwoJCS8vZm9vLm1fZm9vID0gMTsgLy8gRXJyb3IuCgkJZm9vLm1fYmFyID0gMTsKCQlyZXR1cm4gZm9vOwoJfQp9OwoKaW50IG1haW4oKQp7CgkvL0ZvbyBmb28xOyAvLyBOby4KCS8vSG9uZXN0RmFjdG9yeTxGb28+IGZhY3Rvcnk7IC8vIE5vcGUuCglIZWlub3VzRmFjdG9yeSBmYWN0b3J5OwoJRm9vIGZvbzIgPSBmYWN0b3J5LkNyZWF0ZUZvbygpOwoJc3RkOjpjb3V0IDw8IGZvbzIubV9iYXIgPDwgc3RkOjplbmRsOwp9