我有以下通用代码,其中有一个实现一些内存 View 的类,并且可以通过多种方式创建该 View 。它用于为某些数据处理功能提供一致的接口(interface)。
class CView
{
...
int m_size;
float *m_data;
};
class CObjectA
{
...
CView m_view;
const CView View() const { return m_view; } // returned
CView View() { return m_view; } // returned
};
class CObjectB
{
...
const CView View() const { return CView(.....); } // constructed
CView View() { return CView(.....); } // constructed
};
void ProcessAdd(CView &dst, const CView &src1, const CView &src2);
void ProcessReverse(CView &dst, const CView &src);
void ProcessMul(CView &dst, const CView &src1, const CView &src2);
现在,我想知道
View
方法是否应该按引用或值返回,以及Process
方法是否应使用引用或值。我想尽量减少复制,但要保持以下功能:CObjectA a1, a2;
CObjectB b1;
... init these somehow
ProcessAdd(a1.View(), b1.View(), a2.View());
似乎编译器不允许我使View()方法返回一个副本,然后通过引用传递给
Process
函数。View
对象的重量很轻,仅指向可以读取或修改的数据。如果
View
方法返回的是CView
而不是CView &
类型,这是否意味着当我将其传递给Process
函数时将进行双重复制吗?获得所需行为的最有效方法是什么?另一个问题是实现const正确性的正确方法是什么?我实际上从不希望过程函数更改
CView
类的成员变量,但是我确实希望CView
类中的数据指针指向Process
的第一个参数(即输出 View )的非常量数据。如果我按值传递,那么拥有const限定词毫无意义吗? 最佳答案
没错,如果按值传递,则无需将其设为const
值。
要回答问题的第一部分,如果返回CView
并将其传递给流程函数,则不会再次复制它,因为ProcessAdd
,ProcessReverse
和ProcessMul
函数的参数都是引用。它将使用传递的相同CView
对象。
如果要封装CView
对象,可以使用一些更清洁的方法对您的应用程序有意义。例如,您可以将 View 方法更改为如下所示:
const CView& View() const { return m_view; }
然后,如果您还有其他要修改的 View 引用,则可以不理会Process函数。但是,由于您似乎正在创建结合了其他
CView
的新对象,因此可以更改函数以直接返回新 View :CView ProcessAdd(const CView &src1, const CView &src2);
您可以按值传递所有
CView
吗?大概。您的示例中的类型很小,因此副本可能不会带来太大的不同。如果对象具有任何重要的指针所有权规则(看起来可能像它们一样),或者可以扩展为包含更多信息,那么您可能只想从一开始就使用引用。