提问人:doa4321 提问时间:2/16/2023 更新时间:2/20/2023 访问量:168
如何在 C++ 中创建 Interface& 类型的向量?
How can I create a vector of type Interface& in C++?
问:
代码如下:
#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_B
Interface_A
答:
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_unique
new
评论
std::vector<Interface_A*>
std::vector<unique_ptr<Interface_A>>
Interface&
,因为任何其他引用都不是 C++ 中的对象,因此您无法创建它们的对象容器。 就在那里。reference_wrapper
unique_ptr
std::unique_ptr<T>
T&
unique_ptr
T&