问题描述
我们的老师正在教我们一些优化技巧,为此她给了我们以下 C++ 代码来优化。
另一点是重载的 Add
函数,我想优化它,但我认为它正确地完成了它的工作。
所以我很困惑,我还能在哪里优化?
解决方法
FStructA
和 FStructB
共享一个公共成员 Key
,因此可以考虑将其移至它们都派生自的基类。
在处理多态类型时,基类几乎总是需要一个 virtual
析构函数,以便在通过基类指针销毁对象时正确调用派生构造函数。这在使用智能指针时尤其重要,例如在多态对象的容器中,正如这段代码所做的那样。
struct
成员默认为 public
,struct
派生自另一个 struct
,默认使用 public
继承,因此明确说明 {{1} } 和 FStructA
继承 FStructB
ly from public
是多余的。
使用 IStruct
时,无需再次指定 override
。 virtual
从本质上暗示 override
。
避免将 virtual
与智能指针构造函数一起使用。改用 new
函数 - std::make_...()
用于 std::make_unique()
,std::unique_ptr
用于 std::make_shared()
。
重载的 std::shared_ptr()
方法可以合并为一个模板方法。
Add()
在处理(智能)指针时与 emplace_back()
相同,尤其是处理必须在容器外部构造的多态类型时。仅当容器本身能够直接构造元素时,使用 push_back()
而不是 emplace_back()
才有意义,然后您只需给 push_back()
构造函数参数。但在这段代码中,情况并非如此。
在您的 emplace_back()
循环中,您正在获取 range-for
按值,这将复制 DataElement
中的每个 shared_ptr
,因此在它们进入和离开作用域时递增和递减它们的引用计数。虽然这很好,但这是不必要的开销。您应该改为参考 DataElements
。事实上,在迭代任何容器时,您通常应该使用引用,除非您确实需要副本,或者制作副本的开销可以忽略不计(即,使用平凡类型)。
在声明变量时考虑尽可能使用 DataElement
,尤其是在处理模板类型时。这在 auto
循环中特别有用。
不要将 range-for
与 static_cast
的原始指针一起使用,而是使用 shared_ptr
来维护正确的共享所有权语义。
不要不必要地复制对象。您正在取消引用 static_pointer_cast
的结果,然后制作对象的副本,然后您正在处理副本,而不是原始对象。这有时很有用,但此代码不是其中之一。使用指针或引用来避免复制。
除非确实需要,否则不要将基类强制转换为派生类。如果您有多态类型(如此代码所做的那样),请尽可能使用多态行为(即虚拟方法)。正确的多态处理逻辑不应该关心它操作的是什么类型。
当 static_cast
足够时不要使用 std::shared_ptr
。 std::unique_ptr
具有 std::shared_ptr
没有的开销(引用计数、控制块等)。共享所有权有其用途,但此代码并未展示它们。
话虽如此,请尝试更像这样的事情:
std::unique_ptr