请考虑以下代码段
template <typename T>
void MyDynamicArray<T>::resize(size_t count)
{
size_t prev_count = Count();
if(count < prev_count)
{
DestroyMemory(prev_count, count);
}
else if(count > prev_count)
{
Reserve(count);
for(size_t i=prev_count; i<count; i++)
{
// change in function call
m_block.DefaultConstruct();
}
}
}
这是同一功能的重载
template<typename T>
void MyDynamicArray<T>::resize(const T &object, size_t count)
{
size_t prev_count = Count();
if(count < prev_count)
{
DestroyMemory(prev_count, count);
}
else if(count > prev_count)
{
Reserve(count);
for(size_t i=prev_count; i<count; i++)
{
// change in function call
m_block.CopyConstruct(object);
}
}
}
一种方法,我认为重构resize函数是提供const T * pObject作为默认参数。并检查是否提供,然后调用CopyConstruct。
另一种方法是提供一个调整大小调整另一个调整大小的包装器。
最好的方法是什么?
答案 0 :(得分:0)
在任何可能的情况下,都没有普遍适用的“最佳方法”。例如,如果代码膨胀不是一个问题,你可以有一对外观到一个公共函数,将一个适当的lambda传递给公共函数:
template <typename T>
void MyDynamicArray<T>::resize(size_t count)
{
resize_common(count, [] { m_block.DefaultConstruct(); });
}
template <typename T>
void MyDynamicArray<T>::resize(const T &object, size_t count)
{
resize_common(count, [&] { m_block.CopyConstruct(object); });
}
template <typename T, typename lambda_t>
void MyDynamicArray<T>::resize_common(size_t count, lambda_t &&lambda)
{
size_t prev_count = Count();
if(count < prev_count)
{
DestroyMemory(prev_count, count);
}
else if(count > prev_count)
{
Reserve(count);
for(size_t i=prev_count; i<count; i++)
{
lambda();
}
}
}
如果代码膨胀是一个问题,那么你自己作为一种可能性提供的变体:
template <typename T>
void MyDynamicArray<T>::resize(size_t count)
{
resize_common(count, null);
}
template <typename T>
void MyDynamicArray<T>::resize(const T &object, size_t count)
{
resize_common(count, &object);
}
template <typename T>
void MyDynamicArray<T>::resize_common(size_t count, const T *object)
{
size_t prev_count = Count();
if(count < prev_count)
{
DestroyMemory(prev_count, count);
}
else if(count > prev_count)
{
Reserve(count);
for(size_t i=prev_count; i<count; i++)
{
if (object)
m_block.CopyConstruct(*object);
else
m_block.DefaultConstruct();
}
}
}
我确信人们可以想到一些相同的变体。最重要的是回答“哪一个是最好的”,必须考虑到您的个人要求,考虑每个替代实施满足要求的程度,并选择其中一个。代码膨胀应该最小化吗?整体表现是个问题吗?等...
答案 1 :(得分:0)
一种解决方案是创建一个虚拟对象,您可以将其传递给新函数a
以指示它是默认构造:
m_block.Construct()
我们在最后使用的是:
struct default_construct_t { };
现在您只需为template <typename T>
void MyDynamicArray<T>::resize(size_t count) {
resize(count, default_construct_t());
}
template <typename T, typename Obj>
void MyDynamicArray<T>::resize(size_t count, Obj const& obj)
{
size_t prev_count = Count();
if(count < prev_count)
{
DestroyMemory(prev_count, count);
}
else if(count > prev_count)
{
Reserve(count);
for(size_t i=prev_count; i<count; i++)
{
// change in function call
m_block.Construct(obj);
}
}
}
和Construct(default_construct_t )
提供重载。