关于用用户定义的方法扩展C ++ STL容器的更好方法的建议 [英] Advice on a better way to extend C++ STL container with user-defined methods
问题描述
我从C ++ STL容器继承,并添加我自己的方法。理由是,对于客户,它将看起来作为一个常规列表,但具有应用程序特定的方法,他们可以很容易地被称为。
这工作正常,但我已经阅读了许多关于不继承从STL的帖子。有人可以提供具体的建议,我如何写下面的代码更好的方式?
class Item
{
int a;
int b;
int c;
int SpecialB()
{
return a * b + c;
}
};
class ItemList:public std :: vector< Item>
{
int MaxA()
{
if(this-> empty())
throw;
int maxA =(* this)[0] .a;
for(int idx = 1; idx< this-> size(); idx ++)
{
if((* this)[idx] maxA)
{
maxA =(* this)[idx] .a;
}
}
return maxA;
}
int SpecialB()
{
if(this-> empty())
throw;
int specialB =(* this)[0] .SpecialB();
for(int idx = 1; idx {
if((* this)[idx] .SpecialB < specialB)
{
specialB - =(* this)[idx] .c;
}
}
return specialB;
}
int AvgC()
{
if(this-> empty())
throw;
int cSum = 0;
for(int idx = 0; idx {
cSum + =(* this)[idx] .c;
}
return cSum / this-> size(); // average
}
};
EDIT :感谢您提供一系列深思熟虑的答案。
为什么你需要以这种方式扩展向量?
与您的函子使用标准< algorithm>
。
std :: min_element
, std :: max_element
int max_a = std :: max_element
(
v.begin(),
v.end(),
boost :: bind(
std :: less< int>(),
bind(& Item :: a,_1),
bind(& Item :: a,_2)
)
) - &
std :: accumulate
- 用于计算费用
const double avg_c = std :: accumulate(v.begin(),v.end(),double(0),boost :: bind(Item :: c,_1))/ v.size (); // ofcourse check size before divide
您的ItemList :: SpecialB()可以重写为:
int accumulate_func(int start_from,int result,const Item& item)
{
if(item.SpecialB ()< start_from)
{
result - = item.SpecialB();
}
return result;
}
if(v.empty())
{
throw someoneghing(empty vector);
}
const int result = std :: accumulate(v.begin(),v.end(),v.front(),boost :: bind(& accumulate_func,v.front ,_1,_2));
BTW:如果你不需要访问成员,你不需要继承。 p>
I inherited from C++ STL container and add my own methods to it. The rationale was such that to the clients, it will look act a regular list, yet has application-specific methods they can readily be called.
This works fine, but I have read numerous posts about not inheriting from STL. Can someone provide a concrete advice of how I might write the code below in a better way?
class Item
{
int a;
int b;
int c;
int SpecialB()
{
return a * b + c;
}
};
class ItemList : public std::vector<Item>
{
int MaxA()
{
if( this->empty() )
throw;
int maxA = (*this)[0].a;
for( int idx = 1; idx < this->size(); idx++ )
{
if( (*this)[idx].a > maxA )
{
maxA = (*this)[idx].a;
}
}
return maxA;
}
int SpecialB()
{
if( this->empty() )
throw;
int specialB = (*this)[0].SpecialB();
for( int idx = 1; idx < this->size(); idx++ )
{
if( (*this)[idx].SpecialB() < specialB )
{
specialB -= (*this)[idx].c;
}
}
return specialB;
}
int AvgC()
{
if( this->empty() )
throw;
int cSum = 0;
for( int idx = 0; idx < this->size(); idx++ )
{
cSum += (*this)[idx].c;
}
return cSum / this->size(); // average
}
};
EDIT: Thanks for a bunch of thoughtful answers. I will create helper functions instead and from now on will never inherit from STL containers.
why you need extend vector in this way?
use standard <algorithm>
with your functors.
e.g.
std::min_element
, std::max_element
int max_a = std::max_element
(
v.begin(),
v.end(),
boost::bind(
std::less< int >(),
bind( &Item::a, _1 ),
bind( &Item::a, _2 )
)
)->a;
std::accumulate
- for calculate avarage
const double avg_c = std::accumulate( v.begin(), v.end(), double( 0 ), boost::bind( Item::c, _1 ) ) / v.size(); // ofcourse check size before divide
your ItemList::SpecialB() could be rewrited as:
int accumulate_func( int start_from, int result, const Item& item )
{
if ( item.SpecialB() < start_from )
{
result -= item.SpecialB();
}
return result;
}
if ( v.empty() )
{
throw sometghing( "empty vector" );
}
const int result = std::accumulate( v.begin(), v.end(), v.front(), boost::bind( &accumulate_func, v.front(), _1, _2 ) );
BTW: if you don't need access to members, you don't need inheritance.
这篇关于关于用用户定义的方法扩展C ++ STL容器的更好方法的建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!