我有以下问题:
让我们假设我有一个包含100个对象的向量,因此创建一个副本是很糟糕的。
class MyClass
{
private:
vector<MyObject> mVector;
};
//return by reference
vector<object>& MyClass::GetVector1()
{
return mVector;
}
vector<object>* MyClass::GetVector2()
{
return &mVector;
};通过引用返回是快速的,并没有生成副本。向量应该在MyClass中仍然可用,因此我不想移动它。但是,使用这个GetVector()方法的最佳方法是什么?
class MyOtherClass
{
private:
vector<MyObject>* myVector;
vector<MyObject>& myVector2;
vector<MyObject> myVector3;
MyClass m;
};
myVector2 = m.GetVector1(); //only works in an initializer list!但是,如果在创建对象时无法初始化向量,怎么办?让我们假设我有一个OnInit()方法,它将在需要时被调用:
void MyOtherClass::OnInit()
{
myVector = m.GetVector2(); //no copy using return by reference
myVector = &m.GetVector1(); //no copy returning a pointer
myVector3 = m.GetVector1(); //copy
}很多人告诉我使用像myVector这样的指针是很糟糕的,但是为什么?我应该用smart_pointers代替吗?(请给我一个例子,如何使用上面给出的代码)
或者有更好的方法来获得快速的表现?
编辑:
对于这个答案,请检查下面所选的答案。
此外,我想添加移动语义。
但这在很大程度上取决于代码的用途,有时您真的想要复制,您将无法避免它。如果您知道对象的持续时间比跟踪它的代码长,那么只要您想要应用更改,就可以使用指针,否则可以使用const。
如果您不再需要返回的对象,并且它可能会被销毁,那么您可以使用“按值返回”,这是可以的,因为编译器可能会通过移动来优化它,但是您可以显式地使用movesemantics并将向量移出类,因为向量元素是动态分配的,容器是可移动的。检查此链接:Is returning by rvalue reference more efficient?
发布于 2014-11-26 10:05:14
公共物品是可以的
在这一点上只有一个公共目标。你不需要那个吸气剂
struct X {
std::vector<Y> vec;
X(..) : vec(..) { .. }
};然后,您可以简单地将其用作:
X x(..);
x.vec.some_member_function();
auto& z = x.vec;
z.vec.some_member_function();如果你真的需要
如果您确实需要使用成员函数版本,那么就使用reference,这有点习以为常,尽管它基本上与按指针返回性能相同:
vector<Y>& X::GetVector() {
return mVector;
}然后将其用作:
X x(..);
x.GetVector().some_member_function();
auto& z = x.GetVector();
z.some_member_function();智能指针不适用于此。
智能指针解决了处理资源和描述所有权的问题。在这种情况下,考虑到std::vector已经在内部拥有和处理自己的资源,它们就没有什么意义了。
发布于 2014-11-26 10:52:32
如果myVector可以由初始化程序列表初始化,那么就执行它!否则你必须使用指针。
指针并不坏,它们只是没有引用那么严格。如果myVector接受nullptr/0值,则可以使用指针。当您使用引用时,它会告诉您它不会是null (或者至少不应该是),并且当您想要使用它时,您不需要检查myVector == 0是否是空的。
我应用相同的约定返回值。例如,对我来说,像这样的声明
vector<object>* MyClass::GetVector2()
意味着该函数可能返回nullptr/0,而
vector<object> & MyClass::GetVector2()
不可能。
要安全地使用指针或引用,您必须确保MyClass对象比MyOtherClass对象更有效。在您的示例中,它是满意的,因为MyClass对象是MyOtherClass的成员。
关于你的设计。如果可以通过MyClass::mVector函数访问GetVector(),为什么要初始化引用?另外,你真的需要这样的访问吗?如果MyClass能够维护与mVector相关的所有内容,那就更好了。
https://stackoverflow.com/questions/27146103
复制相似问题