【问题标题】:c++ Factory. Child constructor not accessible from parentc++ 工厂。无法从父级访问子构造函数
【发布时间】:2014-05-31 17:55:08
【问题描述】:

我正在制作一个套接字工厂。我希望每个外部应用程序都使用作为少数类(ServerSocketTCP、ClientSocketTCP、ServerSocketUDP 等)的父类的 Socket 类的接口,因为最终将使用套接字独立于类​​型进行读写,从而简化了使用他们。因此套接字将仅由套接字静态成员(工厂)构造。这就是为什么要保护子构造函数以避免用户创建它们。

这是我得到错误的地方:

class A{
protected:
   A();
public:
   static A* createClass(int _type){
      switch(_type){
       case 0:
         return new B();
       case 1:
         return new C();
       default:
         return nullptr;
      }
   }
}

class B: public A{
protected:
    B();
}

class C: public A{
protected:
    C();
}

然后编译器说B和C的构造函数不能从A访问。有什么办法可以做我想做的事吗?我认为可以访问受保护的子成员,但现在我看到这不是因为访问继承......

【问题讨论】:

    标签: c++ inheritance factory


    【解决方案1】:

    您的代码有问题。除了在类定义之后缺少; 之外,您还以错误的方式实现了工厂。

    一般来说,您有一个生产产品的生产者。这些产品都共享一个普通用户不应该实例化的基类(例如纯虚拟或受保护的ctor)。根据客户的选择,生产者创建一个产品实例并将其返回。因此,如果您的产品 ctor 是 private,您需要将生产者声明为 friend,以便能够访问相应的 ctor。

    现在生产者提供了一些指向基础产品的指针,该基础产品可以向下转换为您需要的类型。所以一个编译示例(选择你的并相应地修改它)将如下所示:

    class Producer;
    class BaseProduct {
        protected:
        BaseProduct() {}
    };
    
    class Product_B : public BaseProduct { 
        friend class Producer;
        private:
            Product_B();
    };
    
    class Product_C : public BaseProduct {
        friend class Producer;
        private:
            Product_C();
    };
    
    class Producer{
        private:
            Producer();
        public:
            static BaseProduct* createProduct_Class(int _type){
                switch(_type){
                    case 0:
                        return new Product_B;
                    case 1:
                        return new Product_C;
                    default:
                        return nullptr;
                }
            }
    };
    

    请注意,错误地使用工厂模式会很快导致反模式。

    编辑:另外,您不应该忘记扩展您的生产者类来管理删除等。有许多书籍和网站可以处理各种模式。一本好书是《Bernd Brügge 的面向对象的软件工程》,当然还有很多。

    【讨论】:

    • 注意不要偏离工厂模式设计的问题:您可以描述并提出更好的方法,但主要问题是可访问性问题
    【解决方案2】:

    在您给出的代码中,工厂方法甚至看不到 B 和 C 类定义,因此无论父级是否可以访问子级的受保护成员(它不能,正如 Marco A.所指出的那样)。

    您需要将工厂方法的实现移动到一个可以查看所有类定义的 cpp 文件中。然后你会得到关于被保护的构造函数的错误,你可以适当地处理这些错误(大概是通过交朋友)。

    【讨论】:

      【解决方案3】:

      是的,编译器在抱怨,因为 B 和 C 构造函数和 `protected,并且不存在友谊。所以 A 不能调用那些构造函数。

      正确的设计是将Factory类型从类层次结构中分离出来,而不是放在基类中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-13
        • 1970-01-01
        • 2017-09-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多