2012-07-13 100 views
2

一些背景优先:多级继承和dynamic_cast

我正在研究一些实现UI接口的遗留代码。代码的构造方式是它有一个基类(实际上是一个结构体),然后将其导出到各种图形对象。

WinBase: 
- Button 
- DialogWin 
- (etc...) 
- EditWin 

胜基具有用来密切关注所有每个对象的孩子中的一员WinBase **children。这些孩子在运行期间以标准的new []/delete []方式创建和销毁。

这些对象的所有方法/函数都假定它们正在接收指向WinBase对象的指针,并且dynamic_cast<>用于确保/验证是否正在使用适当的指针。

稍后改变到代码增加了两个类/结构(ListBoxTextBox)时,从EditWin而这又是从WinBase衍生而得。

所以...我有指向WinBase,它被铸造为ListBoxTextBox。正如我所说,在整个代码中都使用了dynamic_cast<>,但我不确定在调用像这个构造函数这样的函数时它有多安全。

如何安全是直接从WinBase转换为ListBox,反之亦然(例如)?

+1

以什么方式安全?如果运行时类型不允许转换,dynamic_cast <>'将评估为NULL指针。只要你检查结果是非空的,你就很安全。如果这不是问题,那么您确实需要提供更多细节,以及您特别困惑的代码(以及以何种方式)。 – pmdj 2012-07-13 11:45:58

+0

而不是返回0,如果我没有弄错,它会抛出一个'std :: bad_cast'异常。 – jogojapan 2012-07-13 11:48:22

+1

@jogojapan如果使用指针,总是返回0。 – ForEveR 2012-07-13 11:49:24

回答

0

首先,为什么你想投一个WinBaseListBox当一个ListBox被给予期待WinBase的方法?如果你需要在那里演员,你应该重新考虑设计,因为期望WinBase只能在WinBase's接口上操作的方法。

如果且仅当,ListBoxWinBase(直接或间接地)衍生的,可以随时从ListBox*转换为WinBase*(或参考),因为一个列表框IS AWinBase

以另一种方式投射并不安全,因为您永远不会知道您得到的WinBase*实际上是ListBox*还是别的什么,这就需要麻烦。您当然可以使用dynamic_cast<>来测试它是否为ListBox*,但任何动态演员都需要审查您的设计。

特别是那种在构造函数中调用麻烦的下调函数,因为当你没有得到你想要的东西时,你的代码应该做什么?抛出异常,作为唯一的出路不是这样一个好主意,并在最好的avoided at all(除非你知道你在做什么)。

+0

有问题的代码是遗留代码,因此作者可能无法重新设计它以避免动态转换。而'dynamic_cast'并不总是一件坏事。像其他所有内容一样,它有其用途,即[非周期性访问者](http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CE8QFjAA&url=http%3A%2F%2Fwww .objectmentor.com%2Fresources%2Farticles%2Facv.pdf&EI = VhIAUNDpMsLj0QG2z7H0Bw&USG = AFQjCNGMyoy2E1JAuc_3CHEZnsq_nS8H4Q)。 – 2012-07-13 12:20:27

+0

当然,那是真的。然而,OP似乎并不十分熟悉C++的继承细节,这些细节很容易被浏览到。我的意图是指出两个方向都可以,一个总是安全的,另一个是,不是:-) – 2012-07-13 12:40:11

+0

因为我改变了这段代码,我一直在阅读有关继承的微妙之处;)和我的主要这里值得关注的是,如果我可以在向WinBase上传时跳过中间对象,或者我必须执行一系列强制转换以达到基类。 – 2012-07-13 13:23:36