如何在 C++ 中创建 Interface& 类型的向量?

How can I create a vector of type Interface& in C++?

提问人:doa4321 提问时间:2/16/2023 更新时间:2/20/2023 访问量:168

问:

代码如下:

#include <iostream>


class Interface_A
{
  public:virtual bool dothething () = 0;
};


class Inherit_B:public Interface_A
{
  bool dothething ()
  {
    std::cout << "Doing the thing in B\n";
    return true;
  }
};

class Inherit_C:public Interface_A
{
  bool dothething ()
  {
    std::cout << "Doing the thing in C\n";
    return true;
  }
};

/**This works */
Interface_A& makeBC ()
{
 #ifdef make_B
  return *(new Inherit_B ());
 #elif make_C
  return *(new Inherit_C());
 #endif
}

/**This doesn't work 
Interface_A makeC ()
{
 #ifdef make_B
  return ((Interface_A) (new Inherit_B ()));
 #elif make_C
  return ((Interface_A) (new Inherit_C ()));
 #endif
}
*/

int main ()
{
  Interface_A& obj = makeBC ();
  obj.dothething();
  // ultimate goal is to make a vector of type <Interface_A&>
  return 0;
}

我想最终创建一个类型的向量,但我似乎找不到一种方法来做到这一点。创建类型的向量也可以,但据我了解,c++ 不允许创建对抽象类型的指针引用。
我不能使用返回类型,因为它被多个类继承,并且活动类是在编译时确定的。 我不能使用智能指针,因为性能是代码的一个极其关键的方面。
我该如何对此做出通用解决方案?
<Interface_A&><Interface_A>Inherit_BInterface_A

C++ C++11 指针 接口 按引用传递

评论

0赞 Botje 2/16/2023
到底有什么问题?甚至更好的是?std::vector<Interface_A*>std::vector<unique_ptr<Interface_A>>
2赞 Swift - Friday Pie 2/16/2023
Interface&,因为任何其他引用都不是 C++ 中的对象,因此您无法创建它们的对象容器。 就在那里。reference_wrapper
0赞 JaMiT 2/16/2023
“我不能使用智能指针,因为性能是代码的一个极其关键的方面。--你有实验证据支持这一点吗?从理论上讲,引用具有与原始指针相同的性能特征。未泄漏的原始指针具有与 相同的性能特征(在典型用法中)。那么,使用引用的收益在哪里呢?unique_ptr
0赞 doa4321 2/16/2023
@JaMiT 我有过多的证据来支持我的陈述。我之所以尽量不使用智能指针,是因为英特尔 vTunes 分析器显示,使用智能指针和映射是在代码中完成的两个最耗时的操作。我打算使用原始指针,但问题是我正在处理不同团队的代码库,并且我不想更改返回引用的函数签名。
1赞 Yakk - Adam Nevraumont 2/17/2023
为什么你认为智能指针比引用更贵?使用 a 和 a 生成的程序集将无法区分,除了 will remember to delete the object 和 will leak。std::unique_ptr<T>T&unique_ptrT&

答:

4赞 463035818_is_not_an_ai 2/16/2023 #1

std::reference_wrapper允许您在容器中存储引用。但是,您不需要引用。引用是指对象。您需要的是将对象存储在某个地方,并在向量中保留指向它的指针。那是.std::vector<std::unique_ptr<Interface>>

我不能使用智能指针,因为性能是代码的一个极其关键的方面。

这是一个有争议的问题。当您决定使用继承和运行时多态性时,您已经购买了某种级别的间接性。智能指针不会带来额外的开销,但它们是您已经处于的情况的正确工具。

如果要避免这种级别的间接性,则应重新考虑运行时多态性的使用。

...活动类在编译时确定

我们开始了......您不需要运行时多态性。您的示例过于模糊和抽象,无法提出更好的设计(模板?但是,当您不需要运行时 polymorphsim 时,您当然不想为此付费。


创建 <Interface_A> 类型的向量也可以,但据我了解,c++ 不允许创建对抽象类型的指针引用。

你可以使基类成为非抽象的,但由于对象切片,这样就不是正确的使用方式了。请参阅什么是对象切片?vector<Interface_A>

评论

0赞 Swift - Friday Pie 2/16/2023
What you need is to store the object somewhere and keep a pointer to it...这适用于时间紧迫的情况。 不,在大多数情况下不是。尤其是在 OP 中。他更愿意使用一些免费存储的替代品,某种内存池。Thats a std::vector<std::unique_ptr<Interface>>
1赞 463035818_is_not_an_ai 2/16/2023
@Swift-FridayPie,他们不能使用任何类型的分配和unique_ptr吗?不确定,但实际上我认为重要的一点是它们根本不需要指针或继承。或者也许他们这样做了。从问题和发布的代码来看,不清楚他们为什么首先使用摘要。似乎它都可以是模板。Interface_A
0赞 Swift - Friday Pie 2/16/2023
没错,但我可以怀疑原因,因为我从事过类似的项目。当这种事情对时间要求严格时,一个常见的情况是通信协议的 API,用于具有时间限制的响应。然后,该接口可能是用于操作数据源或描述常见操作的 API。在某些情况下,它可以通过静态多态性来完成,除非项目的架构假设批量处理不同的数据类型,即在同一位置处理不同类型的消息包并且数据动态变化。
0赞 doa4321 2/16/2023
@Swift - 你猜对了。这确实是我试图优化的通信接口层。
1赞 463035818_is_not_an_ai 2/16/2023
@doa4321只是为了方便,这也是让纯粹主义者拥有“永不原始”的吟唱;)的原因。你可以在这里看到一个可能的实现 en.cppreference.com/w/cpp/memory/unique_ptr/make_unique,不要太编译,如果你愿意,你也可以在 c++11 中拥有它。make_uniquenew