如何避免 C++为特定的类方法进行强制转换?设计模式?
假设我有这样的事情:
class Father {
public:
virtual int genericMethod (void) =0;
};
class Son1: public Father {
public:
int genericMethod ()
{ }
};
class Son2: public Father {
public:
int genericMethod ()
{ }
int specifClassMethod()
{ }
};
主要我做了以下事情:
Father * test = new Son2();
test->specifClassMethod(); //Can't do this! It is specific of Class Son2 and is not a virtual method in class Father!
这里的主要问题是知道通过 Father 接口访问 Son2 特定方法的更好方法。我想知道是否有设计模式可以解决这个问题或其他方法。我不想进行强制转换,也不想在代码中添加大量“if”。
问候,
爱德华多
Suppose I have something like this:
class Father {
public:
virtual int genericMethod (void) =0;
};
class Son1: public Father {
public:
int genericMethod ()
{ }
};
class Son2: public Father {
public:
int genericMethod ()
{ }
int specifClassMethod()
{ }
};
In the main I do the following:
Father * test = new Son2();
test->specifClassMethod(); //Can't do this! It is specific of Class Son2 and is not a virtual method in class Father!
The main question here is to know the better way to access Son2 specific method through Father interface. I want to know if there is a Design Pattern to solve this or another way. I don't wanna to do casts and I don't wanna to put lots of 'if' in my code.
Regards,
Eduardo
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
首先,您不能为“Father”类创建实例,因为它是一个抽象类(具有 virtual int genericMethod (void) =0; -pure virtual function)。相反,可以为其分配一个实例。 ..
喜欢
First of all,you can not create an instance for the class "Father" because it is an abstract class(which has virtual int genericMethod (void) =0; -pure virtual function).Instead an instance can be assigned to it....
Like
如果您确实有特定于
Son2
的内容,那么您应该使用dynamic_cast<>
。如果它可以作为虚拟函数添加到具有默认空行为的基类中,那么您可以在不进行强制转换的情况下解决您的问题(但这不是您在问题中所述的想要做的事情)一种设计解决您的问题的模式是使用 代理对象。该对象将具有易于调用的所有方法,并将它们委托给真实对象或不委托给真实对象。
代理模式的优点:
Son
类没有多余的东西If you really have something specific to
Son2
thendynamic_cast<>
is what you should use. If it is something that could be added as a virtual function to the base class with a default empty behaviour, then you can solve your issue without a cast (but that is not what you wanted to do as you stated in the question)One design pattern to solve your issue is to use a proxy object. That object would have all the methods susceptible to be called and delegate them to the real object or not.
Advantages of the proxy pattern:
Son
classes clean from extra stuff您可以
static_cast(test)->specifClassCmethod();
但这仅在Father * test = new Son2();
时有效You can
static_cast<Son2*>(test)->specifClassCmethod();
but that only works ifFather * test = new Son2();
不可以。要调用仅存在于子类中的方法,您必须强制转换为子类。
虽然您可以创建一个将函数名称映射到函数的映射,但可以从子类的构造函数中将函数添加到其中,然后使用类似
test->callMethod("name");
的内容必须使所有这些方法具有相同的签名或使用可变参数来传递参数,这不是很好。No. To call methods which only exist in a child class, you'll have to cast to the ch ild class.
While you could create a map which maps function names to functions, add your functions to it from the child class' constructor and then use something like
test->callMethod("name");
you'd have to make all those methods have the same signature or use varargs to pass arguments which is not very nice.您也无法通过强制转换合法地解决此问题,因为“测试”指向 Father 对象,而不是 Son2 对象。转换对象类型意味着“相信我,编译器,这个变量实际上保存着 X”。它不会以某种方式神奇地将基础对象转换为派生对象;而是将其转换为派生对象。它只告诉编译器一些你已经知道但它不知道的事情。
如果您希望派生类具有不同的行为,则将该行为移至虚拟方法中——即,想要调用特定CLassMethod() 的代码属于Father 的虚拟方法。
You couldn't legally solve this with a cast, either, because "test" is pointing to a Father object, not a Son2 object. Casting object types means "Trust me, compiler, this variable actually holds X". It doesn't somehow magically convert a base object into a derived object; it only tells the compiler something you already know that it does not.
If you want behavior that differs by derived class, then move the behavior into a virtual method -- i.e., the code that wants to call specificCLassMethod() belongs in a virtual method of Father.
可能的方法是拥有带有可选方法的特定接口,以及在基类中获取此接口的虚拟方法(可能返回零):
用法如下:
Possible approach is to have specific interface with optional methods, and virtual method to get this interface in the base class (which may return zero):
Usage is following:
也许访问者模式就是您正在寻找的模式。
访问者模式如何避免向下转型
Maybe the Visitor-Pattern is the pattern you're looking for.
How Visitor Pattern avoid downcasting