C++ 如何正确返回大向量 vector&getvectorofoo();
我想向其他人提供我的Foo对象列表。这是最好的方法吗?我在这里返回了一个引用,但没有正确复制C++ 如何正确返回大向量 vector&getvectorofoo();,c++,stl,vector,C++,Stl,Vector,我想向其他人提供我的Foo对象列表。这是最好的方法吗?我在这里返回了一个引用,但没有正确复制 调用方可能(意外)修改此列表,对吗?有没有办法避免这种可能性?我可以返回常量向量吗?但是他们也可以修改Foo对象,我在那里做不了多少。10-20个不同的人将编写使用此Foo列表的代码 也将其作为常量返回 vector<Foo*>& getVectorOfFoo(); const vector&getvectorofoo(); 首先不要返回指针列表。 这使得允许
调用方可能(意外)修改此列表,对吗?有没有办法避免这种可能性?我可以返回常量向量吗?但是他们也可以修改Foo对象,我在那里做不了多少。10-20个不同的人将编写使用此Foo列表的代码 也将其作为常量返回
vector<Foo*>& getVectorOfFoo();
const vector&getvectorofoo();
首先不要返回指针列表。这使得允许的行动更加不明确 Boost有一个解决方案(与往常一样)。
返回指针容器。这会将指针公开为普通成员
const vector<Foo *> &getVectorOfFoo();
boost::ptr_vector const&getvectorofoo();
现在用户无法更改返回的向量
例如:
boost::ptr_vector<Foo> const& getVectorOfFoo();
#包括
福班
{
公众:
void plop(){}
void poop()常量{}
};
boost::ptr_vector const&getvectorofoo()
{
静态boost::ptr_vector instance;//使用FOO对象创建并填充容器。
实例。推回(新Foo);
返回实例;
}
int main()
{
boost::ptr_vector const&value=getVectorOfFoo();
值[0]。plop();//失败。不是常量方法(注释掉此行)
值[0]。poop();
}
如前所述,提供对容器的常量访问
但它仍然不是“完美的”,因为您需要向世界公开容器,因此如果您更改它,那么如果界面不再相同,您也会强制用户代码更改
但还有最后的希望:
如果可以使用lambdas(C++0x),那么最好为每个算法提供一个:
#include <boost/ptr_container/ptr_vector.hpp>
class Foo
{
public:
void plop() {}
void poop() const {}
};
boost::ptr_vector<Foo> const& getVectorOfFoo()
{
static boost::ptr_vector<Foo> instance; // Create and fill container with FOO objects.
instance.push_back(new Foo);
return instance;
}
int main()
{
boost::ptr_vector<Foo> const& value = getVectorOfFoo();
value[0].plop(); // Fail. not a const method (comment out this line)
value[0].poop();
}
类MyThingManager
{
公众:
template//注意:可以是非模板,在这种情况下使用std::function
void modify_each_thing(FunctorType f)//如果使用std::function,则可以将实现放在cpp文件中,而不是头文件/内联文件中
{
//进行一些检查,或者生成一个允许修改的内容列表
//然后应用函数(这里我们假设没有为win定义单独的列表实现!)
std::for_each(m_things.begin(),m_things.end(),f);//哦,是的
//然后我们可以应用我们想要的任何东西
检查所有内容是否仍然有效();
通知世界();
}
//这是一个更简单的只读版本
模板
void for_each_things(函数类型f)const{std::for_each(m_things.begin(),m_things.end(),f);}
//如果你想让用户知道需要操作多少东西
size\u t things\u count()常量{return m\u things;}
私人:
std::vector m_things;//可以是任何容器,这与算法是隔离的!
};
用法:
class MyThingManager
{
public:
template< typename FunctorType > // note : could be non-template, in wich case use std::function<>
void modify_each_thing( FunctorType f ) // if you use std::function, you can put the implementation in the cpp file instead of the header/inline
{
// do some checks, or maybe generate a list of Things that you allow to modify
// then apply the function (here we assume we don't have a separate list - implementation defined for the win!)
std::for_each( m_things.begin(), m_things.end(), f ); // oh yeah
// then we can apply anything more we want
check_everything_is_still_valid();
notify_the_world();
}
// here is a simpler read-only version
template< typename FunctorType >
void for_each_thing( FunctorType f ) const { std::for_each( m_things.begin(), m_things.end(), f ); }
// in case you want the user to know how many things to manipulate
size_t things_count() const { return m_things;}
private:
std::vector<Thing> m_things; // could be any container, that's isolated from the algorithm!
};
MyThingManager;
对于_each_thing([](const thing&thing){std::cout将容器的返回类型合并到方法签名中几乎会阻止您在将来使用更合适的替代容器时更改基础容器类型
您至少应该考虑使用<代码> TyBuffs<代码>隐藏实际容器类型,并记录返回对象的最小能力,而不是直接返回<代码>向量< /代码>。< /P>
但您可以考虑提供迭代器接口,比如“代码>您的事情::COSTATIORATER GETFooFixEngor()/<代码>和<代码> GETFoEnEnter()
。这样一来,客户端代码就不能修改底层容器或对象,事实上甚至不需要知道容器类型是什么,从而在将来提供更大的灵活性
如果您确实希望返回一个容器,那么您需要准确地确定语义是什么,从这个问题听起来您希望它是只读的。在这种情况下,您几乎必须将容器复制到另一个包含常量指针而不是非常量指针的
vector
,因此客户端无法修改或者,另一个答案提供了一个使用boost指针容器的非常好的建议。您只需返回向量的常量引用。这样调用方就无法修改它。从讨论和答案中可以明显看出,getVectorOfFoo()是隐式的是一个类的成员函数,向量是该类的成员变量,但在问题的任何地方都没有说明这一点,这很重要。很好的讨论,从大家那里学到了一些东西。谢谢大家。+1,我以前从来没有想过指针容器的这个应用。@MarkB:我也是。喜欢这个。
MyThingManager manager;
manager.for_each_thing( []( const Thing& thing ){ std::cout << "\nA thing : " << thing; } );