我正在尝试为派生类创建一个工厂。我只希望工厂能够创建派生类的实例,因此我创建了基本构造函数protected
;派生类仅使用基类构造函数,因此它们的构造函数是protected
also.
我试图将工厂声明为基类的友元,以便它可以访问protected
构造函数。当我使用这个命令编译时
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 中是不可能的,但我不确定为什么。有人可以解释为什么这行不通,也许还有替代方案吗?
示例代码
#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;
}
当您从基类继承构造函数时,无论您将构造函数放在何处,它都会保留原始构造函数的访问权限using
派生类中的声明。
From §12.9/4 [类.inhctor]
如此声明的构造函数与中的相应构造函数具有相同的访问权限X
. ...
如果您显式向派生类添加构造函数而不是从派生类继承它们,则可以修复该错误Base
.
A(int i) : Base(i) {}
and
B(int i) : Base(i) {}
现场演示
当然,另一个解决方案是Base
的构造函数public
。你也可以让它的析构函数protected
,但这不是必需的,因为由于纯虚拟成员函数,该类无论如何都无法实例化。
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() {}
};
现场演示
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)