返回班级私有会员"large"好做法是什么?
What is the good practice for returning "large" class private member?
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() 复制它吗?首选常量引用而不是 getData2() 有什么性能优势吗?我应该如何从课堂上返回如此"大"的私人成员?
区别在于用户可以用你的DataType
做什么:
- 使用
getData1
它们只能调用标记为const
的成员函数,并访问成员变量,就像它们被声明为常量一样,并且只能在返回引用的对象的生存期内。 - 有了
getData2
用户可以调用他们想要的任何方法,并根据需要进行修改。
使用getData2
的代价是复制:如果DataType
有一个昂贵的复制构造函数,则调用可能会变得更加昂贵。
您可以通过实施写入时复制策略并通过引用计数共享数据来改进这一点。当然,用户可以通过在常量引用上调用复制构造函数来手动制作副本:
DataType dtCopy(obj.getData1());
在此示例中,成员data
似乎是接口的一部分。目前尚不清楚您是否希望在创建类后数据是可变的。如果没有,您可以简单地将 const 数据成员公开为"数据即接口",如下所示:
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;
};
返回大型类私有成员几乎从来都不是一个好的做法。
你应该使用 getData1() 而不是 getData2()。那里不需要复制。
首选getData1()
的原因是因为客户端可以执行const DataType& data = myClass.getData1();
,从而避免复制大数据。
这取决于。通常,最好返回对 const 对象的引用,因为您不能 100% 确定客户端是否需要数据副本。即使客户端确实需要数据副本,它们也可以调用复制构造函数。因此,getData1()
允许一些选择。有了getData2()
你总是必须处理复制构造函数。
const DataType & MyClass::getData1() const
{
return data;
}
^ 这将返回对常量对象的引用。这是一条路。显然,它不允许对对象进行外部修改。
DataType MyClass::getData2() const
{
return data;
}
^ 这不适合"酷孩子"。这将在return data
上调用您的巨大对象的复制构造函数。
在这种情况下,最好通过 const 引用返回,因为它可以避免不必要的复制。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 文件系统:复制功能的速度秘诀是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 返回班级私有会员"large"好做法是什么?