加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 当我知道类型时,如何避免虚拟呼叫?

发布时间:2020-12-16 04:58:44 所属栏目:百科 来源:网络整理
导读:请考虑以下代码段: struct Base { virtual void func() { } };struct Derived1 : Base { void func() override { print("1"); } };struct Derived2 : Base { void func() override { print("2"); } };class Manager { std::vectorstd::unique_ptrBase items
请考虑以下代码段:
struct Base { virtual void func() { } };
struct Derived1 : Base { void func() override { print("1"); } };
struct Derived2 : Base { void func() override { print("2"); } };

class Manager {
    std::vector<std::unique_ptr<Base>> items;

    public:
        template<class T> void add() { items.emplace_back(new T); }
        void funcAll() { for(auto& i : items) i->func(); }
};

int main() {
    Manager m;
    m.add<Derived1>();
    m.add<Derived2>();
    m.funcAll(); // prints "1" and "2"
};

我正在使用虚拟调度,以便从多态对象的std :: vector调用正确的override方法.

但是,我知道多态对象的类型,因为我在Manager :: add< T>中指定了它.

我的想法是通过获取成员函数T :: func()的地址并直接将其存储在某处来避免虚拟调用.但是这是不可能的,因为我需要将它存储为void *并将其转换回Manager :: funcAll(),但我当时没有类型信息.

我的问题是:似乎在这种情况下,我有比平常更多的信息用于多态(用户在Manager :: add< T>中指定派生类型T) – 有什么方法可以使用这种类型信息来防止看似不需要的虚拟电话? (但是,用户应该能够在其代码中创建自己的Base派生类.)

解决方法

However,I know what type the polymorphic objects are,since I specify that in Manager::add<T>.

不,你没有.在添加中,您知道要添加的对象的类型;但您可以像在示例中一样添加不同类型的对象.除非您将Manager参数化为仅处理一种类型,否则funcAll无法静态确定元素的类型.

如果您确实知道了类型,那么您可以非虚拟地调用该函数:

i->T::func();

但是,重申一下,您无法在此静态确定类型.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读