typedef std::vector <std::vector <int>> DataType;
class MyClass
{
public:
const DataType &getData() const;
DataType getData2() const;
private:
DataType data;
};
const DataType &MyClass::getData1() const
{
return data;
}
DataType MyClass::getData2() const
{
return data;
}
我应该避免使用getData1()来复制它吗?更喜欢const引用而不是getData2()是否有任何性能优势?我应该如何归还这样的&#34;大&#34;来自班级的私人会员?
答案 0 :(得分:5)
不同之处在于用户可以使用DataType
:
getData1
,他们只能调用标记为const
的成员函数,并访问成员变量,就像它们被声明为常量一样,并且仅在返回引用的对象的生命周期内。getData2
用户可以调用他们想要的任何方法,并根据需要进行修改。使用getData2
的价格是复制:如果DataType
有一个昂贵的复制构造函数,则调用可能会变得更加昂贵。
您可以通过实施写时复制策略并通过引用计数共享数据来改进这一点。当然,用户可以通过在常量引用上调用复制构造函数来手动复制:
DataType dtCopy(obj.getData1());
答案 1 :(得分:2)
返回一个大班私人成员几乎永远是一个好习惯。
答案 2 :(得分:2)
在此示例中,似乎成员data
实际上是接口的一部分。在创建类之后,您是否打算将数据设置为可变,这一点尚不清楚。如果没有,您可以简单地将const数据成员公开为&#39;数据作为接口&#39;像这样:
typedef std::vector <std::vector <int>> DataType;
class MyClass
{
public:
MyClass(DataType data_)
: data(std::move(data_))
{
}
// data is interface, but it's immutable so perfectly safe
const DataType data;
};
在所有情况下,这将是最佳效率,而且它具有自动线程安全的优势。
如果您打算data
是可变的,那么通常要做的是提供一个const引用访问器和一个可变引用访问器(尽管这实际上在逻辑上等同于简单地在接口上公开数据)
类似的东西:
class MyClass
{
public:
MyClass(DataType data)
: _data(std::move(data))
{
}
// immutable access
const DataType& data() const { return _data; }
// mutable access
DataType& data() { return _data; }
// another option - allow the client to move the data out of me
DataType&& steal_data() {
return std::move(_data);
}
private:
DataType _data;
};
答案 3 :(得分:0)
在这种情况下,通过const引用返回是最好的,因为它可以避免不必要的复制。
答案 4 :(得分:0)
您应该使用getData1()而不是getData2()。那里不需要复制。
答案 5 :(得分:0)
首选getData1()
的原因是因为客户端可以执行const DataType& data = myClass.getData1();
,这可以避免复制大数据。
答案 6 :(得分:0)
这取决于。通常,最好返回对const对象的引用,而不是100%确定您的客户端需要数据副本。即使您的客户端确实需要数据副本,他们也可以调用副本构造函数。因此,getData1()
允许一些选项。使用getData2()
,您始终必须处理复制构造函数。
const DataType & MyClass::getData1() const
{
return data;
}
^这将返回对常量对象的引用。这是一种方法。显然,它不允许外部修改对象。
DataType MyClass::getData2() const
{
return data;
}
^这不适合&#34;酷孩子&#34;。这将在return data
上调用您的巨大对象的复制构造函数。