C ++ 11声明工厂是基类的朋友 [英] C++11 Declaring factory a friend of base class
问题描述
我想为派生类创建一个工厂。我只想让工厂能够创建派生类的实例,所以我已经使基本构造函数 protected
;派生类只使用基类构造函数,所以它们的构造函数也是 protected
。
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.
我试图声明工厂作为基类的一个朋友,以便它可以访问 protected
构造函数。当我使用此命令编译时
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
我收到此错误:
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;
^
导出类的类似错误 B
。
我从stackoverflow.com阅读其他问题的感觉,这是不可能在C + + 11,但我不知道为什么。有人可以解释为什么这将不工作,也许一个替代?
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?
示例代码
#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;
}
推荐答案
一个基类,它保留原始构造函数的访问,而不管你在导出类中使用 c>声明的位置。
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.
来自§12.9/ 4 [class.inhctor]
From §12.9/4 [class.inhctor]
这样声明的构造函数具有相同的访问权限作为
X
中的相应构造函数。 ...
A constructor so declared has the same access as the corresponding constructor in
X
. ...
如果您明确地将构造函数添加到派生类而不是从继承它们, Base
。
You can fix the error if you explicitly add constructors to derived classes instead of inheriting them from Base
.
A(int i) : Base(i) {}
和
B(int i) : Base(i) {}
另一个解决方案,当然是让 Base
的构造函数 public
。你也可以使它的析构函数 protected
,但它不是必要的,因为该类不能被实例化由于纯虚拟成员函数。
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() {}
};
这篇关于C ++ 11声明工厂是基类的朋友的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!