C++11 Declaring factory a friend of base class
c++, c++11, factory, friend, inheritance
Solution
When you inherit a constructor from a base class it retains the access of the original constructor, regardless of where you place the `using` declaration in the derived class.
From §12.9/4 [class.inhctor]
A constructor so declared has the same access as the corresponding constructor in `X`. ...
You can fix the error if you explicitly add constructors to derived classes instead of inheriting them from `Base`.
A(int i) : Base(i) {}
and
B(int i) : Base(i) {}
Live demo
Another solution, of course, is to make `Base`'s constructor `public`. You could also make its destructor `protected`, but it's not necessary since the class cannot be instantiated anyway due to the pure virtual member function.
class Base {
public:
template<class T>
friend T* Create(int);
virtual void say() = 0;
Base(int i): i(i) { } // This won't compile
int i;
protected:
~Base() {}
};
Live demo
Problem
I'm trying to create a factory for derived classes. I only want the factory to be able to create instances of the derived classes so I've made the base constructor `protected`; the derived classes just use the base class constructors so their constructors are `protected` also. I tried to declare the factory as a friend of the base class so that it could access the `protected` constructor. When I compile using this command ``` clang++ -std=c++11 -stdlib=libc++ Friends.cpp -o Friends ``` I get this error: ``` Friends.cpp:23:20: error: calling a protected constructor of class 'A' return new T(i); ^ Friends.cpp:42:16: note: in instantiation of function template specialization 'Create<A>' requested here A* a = Create<A>(1); ^ Friends.cpp:30:25: note: declared protected here using Base::Base; ^ ``` Along with a similar error for derived class `B`. I get the feeling from reading other questions on stackoverflow.com, that this isn't possible in C++11, but I'm not sure why. Can someone explain why this won't work and perhaps an alternative? Example code ``` #include <iostream> using namespace std; // Forward declaration template<class T> T* Create(int i); class Base { public: template<class T> friend T* Create(int); virtual void say() = 0; protected: Base(int i): i(i) { } // This won't compile int i; }; // Factory for Base class template<class T> T* Create(int i){ return new T(i); } class A: public Base { public: using Base::Base; void say() { cout << "I am A and have a value of " << i << endl; } }; class B: public Base{ public: using Base::Base; void say() { cout << "I am B and have a value of " << i << endl; } }; int main(){ cout << "I'm creating A." << endl; A* a = Create<A>(1); a->say(); cout << "I'm creating B." << endl; B* b = Create<B>(2); b->say(); return 0; } ```