标签: dynamic-dispatch

基于模板参数的C++动态调度仿真

为了这个问题,这被大大简化了.说我有一个层次结构:

struct Base {
    virtual int precision() const = 0;
};

template<int Precision>
struct Derived : public Base {

    typedef Traits<Precision>::Type Type;

    Derived(Type data) : value(data) {}
    virtual int precision() const { return Precision; }

    Type value;

};
Run Code Online (Sandbox Code Playgroud)

我想要一个带有签名的非模板函数:

Base* function(const Base& a, const Base& b);
Run Code Online (Sandbox Code Playgroud)

函数结果的具体类型与任何一个类型相同ab具有更大的类型Precision; 像下面的伪代码:

Base* function(const Base& a, const Base& b) {

    if (a.precision() > b.precision())

        return new A( ((A&)a).value + A(b.value).value );

    else if (a.precision() < b.precision()) …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism rtti dynamic-dispatch

5
推荐指数
1
解决办法
2828
查看次数

为什么C++不允许您请求指向最派生类的指针?

(这个问题应该通过对Stroustrup的引用来回答.)

能够请求指向最派生类的指针似乎非常有用,如下所示:

class Base { ... };
class DerivedA { ... };
class DerivedB { ... };
class Processor
{
  public:
  void Do(Base* b) {...}
  void Do(DerivedA* d) {...}
  void Do(DerivedB* d) {...}
};

list<Base*> things;
Processor p;
for(list<Base*>::iterator i=things.begin(), e=things.end(); i!=e; ++i)
{
    p.Do(CAST_TO_MOST_DERIVED_CLASS(*i));
}
Run Code Online (Sandbox Code Playgroud)

但是c ++中没有提供这种机制.为什么?

更新,激励示例:

假设您没有Base和Derived and Processor,而是拥有:

class Fruit
class Apple : public Fruit
class Orange: public Fruit

class Eater
{
   void Eat(Fruit* f)  { ... }
   void Eat(Apple* f)  { Wash(f); ... }
   void …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance multiple-dispatch rtti dynamic-dispatch

5
推荐指数
4
解决办法
588
查看次数

为什么虚函数表指针(vfptr)在C++中不能是静态的?

如果虚拟函数表对于类的所有对象都是相同的,那么为什么指向该表的指针(vfptr)不能是静态的并且在所有对象之间共享?

c++ virtual-functions dynamic-dispatch

5
推荐指数
1
解决办法
1100
查看次数

Fragile Base Class是"继承打破封装"的唯一原因吗?

正如"四人帮"在" 设计模式 "中所述:" 人们经常说 '继承打破了封装'",在"面向对象编程语言中的封装和继承"中解释Snyder.

然而,每次我读" 继承断裂包封 ",这要求背后的原因要么依稀解释的,或与所述的一个例子说明脆基类的问题.

在阅读论文时,我感觉真正打破封装的唯一继承属性是downcalls,这是开放递归(动态调度打开this)允许的特性,并定义为"当超类方法调用在子类中重写的方法时",根据Ruby&Leavens在"安全地创建正确的子类而不看超类代码"中的说法.
此外,根据Aldrich在"选择性开放递归:脆弱基类问题的解决方案"中的说法,开放递归显然是导致脆弱基类问题的原因.

因此,如果脆弱基类问题是"继承打破封装"的唯一原因,那么可以更清楚地说,下调会破坏封装.由于存在一些解决方案以避免在使用继承时进行下调,因此继承本身并不真正涉及破坏封装.此外,四人帮提出的取消继承的委托模式也可以允许开放递归和下调,因为委托人的context(this)由委托使用(这可能导致一种脆弱的委托类问题).

因此,我的问题是:
脆弱的基类问题是否被称为"继承打破封装"的唯一原因?

oop inheritance encapsulation late-binding dynamic-dispatch

5
推荐指数
2
解决办法
427
查看次数

如何将非对象安全的 Trait 包装在对象安全的 Trait 中?

我最初在尝试创建一个 Rayon ParallelIterator 时遇到了这个问题,该flat_map操作被应用于动态次数,请参阅 Rayon 问题跟踪器上的这篇文章

注意:我也在 Rust 用户论坛上问过同样的问题(请参阅此处),但 StackOverflow 可能是解决此问题的更好场所。

对于标准(即串行执行)Iterators 以下工作:

fn fancy<Input, Output, Item>(input: Input, depth: usize) -> Output
where
    Input : IntoIterator<Item = Item>,
    Output : std::iter::FromIterator<Item>,
    Item : Copy + std::ops::Add<Output = Item>,
{
    let mut iter: Box<dyn Iterator<Item = Item>> = Box::new(input.into_iter());
    for _ in 0..depth {
        iter = Box::new(iter.flat_map(|x| vec![x, x + x].into_iter()));
    }
    iter.collect()
}
Run Code Online (Sandbox Code Playgroud)

ParallelIterator然而,当使用 Rayon 的s 时,事情变得不确定:ParallelIterator需要实现它的类型是Sized,使它们非对象安全,因此不可能作为特征对象传递。因此,以下直接翻译不起作用: …

iterator traits dynamic-dispatch rust

5
推荐指数
0
解决办法
142
查看次数

非虚拟基础的多态成员类

First if all, of the polymorphism answers I find, it's always like "if the base function is not virtual and the derived object is stored in a pointer of type base, then you cannot call the derived function". But they never tell you what to do when you want to do exactly that. And that's what I need to do.

I have a base class B that I have no control over. It's open source (TwoWire from Arduino library) …

c++ polymorphism arduino type-erasure dynamic-dispatch

5
推荐指数
1
解决办法
49
查看次数

Smalltalk动态查找优化

在Smalltalk中,在运行时查找的方法可能涉及大量的步骤,因为一个子类的方法字典中不包含它的超类的方法,和一个指针追逐,需要找对方法.优化将是每个子类在其方法字典中存储所有超类方法.
问题:如何做到这一点?

一个明显的缺点是空间成本,但我只是想知道如何在Smalltalk中完成这项工作?这与为最近调用的方法创建单独的缓存不同.

smalltalk dynamic-dispatch

4
推荐指数
1
解决办法
162
查看次数

如何访问 dyn 结构体的字段?

最近我一直在学习高级 Rust。作为其中的一部分,我正在学习使用动态调度。

在我的修补过程中,我遇到了一些问题。由于某种原因,我似乎无法访问已使用框和动态调度分配给变量的结构字段。例如,

fn main() {
    let z: Box<dyn S>;
    z = Box::new(A::new());

    println!("{}", z.val);
}

trait S {
    fn new () -> Self where Self: Sized;
}


struct A {
    val: i32,
}

impl S for A {
    fn new () -> A {
        A {val: 1}
    }
}

struct B {
    val: i32
}

impl S for B {
    fn new() -> B {
        B {val:2}
    }
}
Run Code Online (Sandbox Code Playgroud)

产生错误消息“错误[E0609]:val类型上没有字段Box<dyn S>

有什么方法可以访问这些字段,还是我需要拼凑一个解决方法?

dynamic-dispatch rust

4
推荐指数
1
解决办法
1505
查看次数

虚拟函数和虚函数表如何工作?

虽然 C++ 标准将虚拟调度的实现留给了编译器,但目前只有 3 个主要编译器(gcc、clang 和 msvc)。

当您通过指向抽象基类的指针调用抽象基类上的方法时,它们如何实现虚拟调度?构建期间如何设置 vtable?

一个简单的“好像”示例会很有用。

c++ polymorphism language-implementation vtable dynamic-dispatch

4
推荐指数
1
解决办法
266
查看次数

如何根据 Rust 中的字符串选择结构体?

问题陈述

\n

我有一组结构 、ABCD,它们都实现了一个 Trait\n Runnable

\n
trait Runnable {\n    fn run(&mut self);\n}\nimpl Runnable for A {...}\nimpl Runnable for B {...}\nimpl Runnable for C {...}\nimpl Runnable for D {...}\n
Run Code Online (Sandbox Code Playgroud)\n

我还有一个结构体,用作构造、\n 、和实例Config的规范。ABCD

\n
struct Config {\n    filename: String,\n    other_stuff: u8,\n}\n\nimpl From<Config> for A {...}\nimpl From<Config> for B {...}\nimpl From<Config> for C {...}\nimpl From<Config> for D {...}\n
Run Code Online (Sandbox Code Playgroud)\n

在我的程序中,我想解析一个Config实例并根据字段的值构造A,\n B, C …

string dynamic-dispatch rust trait-objects

4
推荐指数
1
解决办法
138
查看次数