首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何为派生类传播好友

如何为派生类传播好友
EN

Stack Overflow用户
提问于 2012-12-17 22:46:08
回答 7查看 21.3K关注 0票数 29

我希望有一个类层次结构,并且只能在Factory中从它创建对象。

示例:

代码语言:javascript
复制
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

有没有办法在派生类中传播友情?有没有其他方法来实现这一行为?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-12-17 23:11:05

不,这是故意不可能的。

是封装带来的问题。

假设有一个管理任何密码的类"PswClass“,这是与其他类的级联好友:如果我继承自PswClass:

代码语言:javascript
复制
 class Myclass : public PswClass {
     .......
 }

通过这种方式,也许我可以访问字段,它将是私有的。

票数 16
EN

Stack Overflow用户

发布于 2012-12-17 23:13:10

友谊既不是继承性的,也不是传递性的,正如这里所描述的:friend class with inheritance

经过一些实验,并利用这个黑客How to setup a global container (C++03)?,我想我已经找到了一种方法,赋予“工厂”创建对象的独特权限。

这是一个快速而肮脏的代码。(向底部滚动以查看黑客行为。)

代码语言:javascript
复制
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
}
票数 4
EN

Stack Overflow用户

发布于 2012-12-17 22:58:12

不能,没有办法从基类继承friend声明。但是,如果您将Base构造函数设为private,则在没有Factory帮助的情况下将无法创建派生类的实例。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13916321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档