我希望有一个类层次结构,并且只能在Factory中从它创建对象。
示例:
class Base
{
protected:
Base(){};
virtual void Init(){};
friend class Factory;
};
class SomeClass : public Base
{
public://I want protected here! Now it's possible to call new SomeClass from anywhere!
SomeClass(){};
void Init(){};
};
class Factory
{
public:
template<class T>
T* Get()
{
T* obj = new T();
obj->Init();
return obj;
}
};
int main()
{
Factory factory;
SomeClass *obj = factory.Get<SomeClass>();
}
我的问题是,我希望只能从工厂创建对象,但我不想在从Base派生的每个类中声明friend class Factory
。
有没有办法在派生类中传播友情?有没有其他方法来实现这一行为?
发布于 2012-12-17 23:11:05
不,这是故意不可能的。
是封装带来的问题。
假设有一个管理任何密码的类"PswClass“,这是与其他类的级联好友:如果我继承自PswClass:
class Myclass : public PswClass {
.......
}
通过这种方式,也许我可以访问字段,它将是私有的。
发布于 2012-12-17 23:13:10
友谊既不是继承性的,也不是传递性的,正如这里所描述的:friend class with inheritance。
经过一些实验,并利用这个黑客How to setup a global container (C++03)?,我想我已经找到了一种方法,赋予“工厂”创建对象的独特权限。
这是一个快速而肮脏的代码。(向底部滚动以查看黑客行为。)
class Object {};
class Factory {
public:
// factory is a singleton
// make the constructor, copy constructor and assignment operator private.
static Factory* Instance() {
static Factory instance;
return &instance;
}
public: typedef Object* (*CreateObjectCallback)();
private: typedef std::map<int, CreateObjectCallback> CallbackMap;
public:
// Derived classes should use this to register their "create" methods.
// returns false if registration fails
bool RegisterObject(int Id, CreateObjectCallback CreateFn) {
return callbacks_.insert(CallbackMap::value_type(Id, createFn)).second;
}
// as name suggests, creates object of the given Id type
Object* CreateObject(int Id) {
CallbackMap::const_iterator i = callbacks_.find(Id);
if (i == callbacks_.end()) {
throw std::exception();
}
// Invoke the creation function
return (i->second)();
}
private: CallbackMap callbacks_;
};
class Foo : public Object {
private: Foo() { cout << "foo" << endl; }
private: static Object* CreateFoo() { return new Foo(); }
public:
static void RegisterFoo() {
Factory::Instance()->RegisterObject(0, Foo::CreateFoo);
}
};
class Bar : public Object {
private: Bar() { cout << "bar" << endl; }
private: static Object* CreateBar() { return new Bar(); }
public:
static void RegisterBar() {
Factory::Instance()->RegisterObject(1, Bar::CreateBar);
}
};
// use the comma operator hack to register the create methods
int foodummy = (Foo::RegisterFoo(), 0);
int bardummy = (Bar::RegisterBar(), 0);
int main() {
Factory::Instance()->CreateObject(0); // create foo object
Factory::Instance()->CreateObject(1); // create bar object
}
发布于 2012-12-17 22:58:12
不能,没有办法从基类继承friend
声明。但是,如果您将Base
构造函数设为private
,则在没有Factory
帮助的情况下将无法创建派生类的实例。
https://stackoverflow.com/questions/13916321
复制相似问题