【发布时间】:2014-07-23 17:37:12
【问题描述】:
我正在尝试为派生类创建一个工厂。我只希望工厂能够创建派生类的实例,所以我创建了基本构造函数protected;派生类只使用基类构造函数,所以它们的构造函数也是protected。
我尝试将工厂声明为基类的友元,以便它可以访问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;
}
【问题讨论】:
-
不确定这是否是您的目标,但可以编译:codepad.org/2l2l1V44。使用受保护的继承和初始化而不是使用 Base::Base。
-
这是你遇到的一个非常奇怪的错误,我的直觉告诉我它应该可以工作,但 gcc 和 clang 似乎都因为你提到的原因拒绝它。
-
在将
friend A* Create<A>(int);添加到类A和类B中的相应代码时,也会在gcc 4.9 上编译。 -
简单地说:“我父母的朋友不一定是我的朋友”
-
@BЈовић 我不同意这是友谊继承问题的重复。 Here's an example 没有友元函数,由于同样的原因仍然无法编译。这里的问题是继承的构造函数在派生类中保留相同的访问权限。
标签: c++ inheritance c++11 factory friend