有哪些“好用”的东西? 动态铸造的例子?

发布于 2024-07-04 13:34:23 字数 203 浏览 6 评论 0原文

我们经常听到/读到应该避免动态转换。 我想知道你认为什么是“很好用”的例子?

编辑:

是的,我知道另一个线程:它确实是当阅读第一个答案时,我提出了我的问题!

We often hear/read that one should avoid dynamic casting. I was wondering what would be 'good use' examples of it, according to you?

Edit:

Yes, I'm aware of that other thread: it is indeed when reading one of the first answers there that I asked my question!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

天邊彩虹 2024-07-11 13:34:23

当通过 C 接口公开对象句柄时,它可用于一定程度的运行时类型安全。 让所有公开的类都继承自一个公共基类。 当接受函数句柄时,首先强制转换为基类,然后动态强制转换为您期望的类。 如果它们传递了一个无意义的句柄,那么当运行时找不到 rtti 时,您将收到异常。 如果它们传入了错误类型的有效句柄,您将得到一个 NULL 指针,并且可以抛出您自己的异常。 如果他们传递了正确的指针,那么你就可以开始了。
这并不是万无一失的,但它肯定比从句柄直接重新解释强制转换更能捕获对库的错误调用,并等到传递错误句柄时某些数据神秘地损坏。

It can be used for a bit of run-time type-safety when exposing handles to objects though a C interface. Have all the exposed classes inherit from a common base class. When accepting a handle to a function, first cast to the base class, then dynamic cast to the class you're expecting. If they passed in a non-sensical handle, you'll get an exception when the run-time can't find the rtti. If they passed in a valid handle of the wrong type, you get a NULL pointer and can throw your own exception. If they passed in the correct pointer, you're good to go.
This isn't fool-proof, but it is certainly better at catching mistaken calls to the libraries than a straight reinterpret cast from a handle, and waiting until some data gets mysteriously corrupted when you pass the wrong handle in.

北陌 2024-07-11 13:34:23

最近的这篇文章给出了一个例子,说明它在哪里派上用场。 有一个基本 Shape 类以及从它派生的 Circle 和 Rectangle 类。 在测试相等性时,很明显,圆形不能等于矩形,尝试比较它们将是一场灾难。 在迭代指向 Shapes 的指针集合时,dynamic_cast 具有双重职责,告诉您形状是否具有可比性,并为您提供适当的对象来进行比较。

向量迭代器不可解除引用

This recent thread gives an example of where it comes in handy. There is a base Shape class and classes Circle and Rectangle derived from it. In testing for equality, it is obvious that a Circle cannot be equal to a Rectangle and it would be a disaster to try to compare them. While iterating through a collection of pointers to Shapes, dynamic_cast does double duty, telling you if the shapes are comparable and giving you the proper objects to do the comparison on.

Vector iterator not dereferencable

落花随流水 2024-07-11 13:34:23

这是我经常做的事情,它并不漂亮,但是简单且有用。

我经常使用实现接口的模板容器,
想象一下像

template<class T>
class MyVector : public ContainerInterface
...

Where ContainerInterface 有基本有用的东西,但仅此而已。 如果我想要一个关于整数向量的特定算法而不暴露我的模板实现,那么接受接口对象并将其动态转换为实现中的 MyVector 是有用的。 示例:

// function prototype (public API, in the header file)
void ProcessVector( ContainerInterface& vecIfce );

// function implementation (private, in the .cpp file)
void ProcessVector( ContainerInterface& vecIfce)
{
    MyVector<int>& vecInt = dynamic_cast<MyVector<int> >(vecIfce); 
    // the cast throws bad_cast in case of error but you could use a
    // more complex method to choose which low-level implementation
    // to use, basically rolling by hand your own polymorphism.

    // Process a vector of integers
    ...
}

我可以向 ContainerInterface 添加一个以多态方式解析的 Process() 方法,这将是一个更好的 OOP 方法,但有时我更喜欢这样做。 当您有简单的容器、大量的算法并且您希望隐藏实现时,dynamic_cast 提供了一个简单而丑陋的解决方案。

您还可以查看双重调度技术。

华泰

Here's something I do often, it's not pretty, but it's simple and useful.

I often work with template containers that implement an interface,
imagine something like

template<class T>
class MyVector : public ContainerInterface
...

Where ContainerInterface has basic useful stuff, but that's all. If I want a specific algorithm on vectors of integers without exposing my template implementation, it is useful to accept the interface objects and dynamic_cast it down to MyVector in the implementation. Example:

// function prototype (public API, in the header file)
void ProcessVector( ContainerInterface& vecIfce );

// function implementation (private, in the .cpp file)
void ProcessVector( ContainerInterface& vecIfce)
{
    MyVector<int>& vecInt = dynamic_cast<MyVector<int> >(vecIfce); 
    // the cast throws bad_cast in case of error but you could use a
    // more complex method to choose which low-level implementation
    // to use, basically rolling by hand your own polymorphism.

    // Process a vector of integers
    ...
}

I could add a Process() method to the ContainerInterface that would be polymorphically resolved, it would be a nicer OOP method, but I sometimes prefer to do it this way. When you have simple containers, a lot of algorithms and you want to keep your implementation hidden, dynamic_cast offers an easy and ugly solution.

You could also look at double-dispatch techniques.

HTH

奢望 2024-07-11 13:34:23

我当前的玩具项目使用了两次dynamic_cast; 一次是为了解决 C++ 中缺乏多重分派的问题(这是一个访问者风格的系统,可以使用多重分派而不是动态类型转换),一次是为了特殊情况下的特定子类型。

在我看来,这两者都是可以接受的,尽管前者至少源于语言缺陷。 事实上,我认为这可能是一种常见的情况; 大多数dynamic_cast(以及一般的许多“设计模式”)都是针对特定语言缺陷的解决方法,而不是目标。

My current toy project uses dynamic_cast twice; once to work around the lack of multiple dispatch in C++ (it's a visitor-style system that could use multiple dispatch instead of the dynamic_casts), and once to special-case a specific subtype.

Both of these are acceptable, in my view, though the former at least stems from a language deficit. I think this may be a common situation, in fact; most dynamic_casts (and a great many "design patterns" in general) are workarounds for specific language flaws rather than something that aim for.

一袭水袖舞倾城 2024-07-11 13:34:23

它非常有用,但是,大多数时候它有用:如果完成工作最简单的方法是进行动态转换,那么它通常是糟糕的面向对象设计的症状,反过来可能会在未来以不可预见的方式导致麻烦。

It is very useful, however, most of the times it is too useful: if for getting the job done the easiest way is to do a dynamic_cast, it's more often than not a symptom of bad OO design, what in turn might lead to trouble in the future in unforeseen ways.

野の 2024-07-11 13:34:23

如果能在 C# 中使用扩展方法那就太好了。

例如,假设我有一个对象列表,我想从中获取所有 id 的列表。 我可以单步执行所有代码并将它们拉出来,但我想将这些代码分段以供重用。

所以类似的东西

List<myObject> myObjectList = getMyObjects();

List<string> ids = myObjectList.PropertyList("id");

会很酷,除了在扩展方法上你不知道传入的类型。

所以

public static List<string> PropertyList(this object objList, string propName) {
    var genList = (objList.GetType())objList;
}

会很棒。

Well it would really be nice with extension methods in C#.

For example let's say I have a list of objects and I want to get a list of all ids from them. I can step through them all and pull them out but I would like to segment out that code for reuse.

so something like

List<myObject> myObjectList = getMyObjects();

List<string> ids = myObjectList.PropertyList("id");

would be cool except on the extension method you won't know the type that is coming in.

So

public static List<string> PropertyList(this object objList, string propName) {
    var genList = (objList.GetType())objList;
}

would be awesome.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文