我正在制作一个插座工厂。我希望每个外部应用程序都使用Socket类的接口,它是几个类(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访问。有什么办法可以做我想要的吗?我认为有可能访问受保护的成员,但现在我看到这不是因为访问继承...
答案 0 :(得分:2)
您的代码存在问题。除了在类定义之后缺少;
之外,您还以错误的方式实现工厂。
一般来说,你有一个生产产品的生产者。这些产品都共享一个普通用户无法实例化的基类(例如纯虚拟或受保护的ctor)。根据客户选择的内容,Producer会创建产品实例并将其交还。因此,如果您的产品是private
,则需要将生产者声明为friend
,以便能够访问相应的ctors。
现在,制作人提供了一些指向基本产品的指针,可以将其下载到您需要的类型。因此,编译示例(选择您的并相应地修改它)将如下所示:
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;
}
}
};
请注意,错误地使用工厂模式可能会导致反模式。
编辑:另外,你不应该忘记扩展你的生产者类来管理删除等。有许多书籍和网站可以处理各种模式。一本好书是“BerndBrügge的面向对象软件工程”,但当然还有很多这样的软件。
答案 1 :(得分:1)
在您提供的代码中,工厂方法甚至无法查看B和C类定义,因此无论父级是否可以访问子级受保护的成员,它都不可能使用它们(它不能,正如Marco A.所指出的那样。
您需要将工厂方法的实现移动到cpp文件,在该文件中可以看到所有类定义。然后你会得到关于被保护的构造函数的错误,你可以适当地处理它们(大概是通过交朋友)。
答案 2 :(得分:1)
是的,编译器抱怨,因为B和C构造函数和`保护,并且没有友谊存在。所以A不能称那些构造函数。
正确的设计是将Factory类型与类层次结构分开,而不是将其放在基类中。