通过引用传递类成员函数返回值C++
Passing class member function return value by reference in C++
我一直在寻找解决这个问题的方法,但似乎找不到。我相信这个一般性问题之前已经在某个地方问过,但希望你能帮助解决我的具体情况......
我有一个包含以下(私有)成员的类模板someClass
:
int size_x;
int size_y;
int size_total;
T * grid;
someClass
包含一个如下所示的构造函数:
someClass (const int x, const int y)
: size_x (x), size_y (y), size_total (x*y)
{
grid = new T [size_total];
}
如下所示的复制构造函数:
someClass (const someClass & rhs)
{
size_x = rhs.size_x;
size_y = rhs.size_y;
size_total = rhs.size_total;
grid = new T [size_total];
memcpy(grid, rhs.grid, size_total*sizeof(T));
}
如下所示的成员函数:
T * retGrid (void) const
{
return grid;
}
以及如下所示的赋值运算符:
someClass & operator= (const someClass & rhs)
{
if (this != &rhs)
{
size_x = rhs.size_x;
size_y = rhs.size_y;
size_total = rhs.size_total;
grid = new T [size_total];
memcpy(grid, rhs.grid, size_total*sizeof(T));
}
return *this;
}
我正在尝试传递以下两个someClass
对象
someClass<double> *I1 = new someClass<double>(10,10);
someClass<double> I2 = *I1;
到具有以下原型的 someClass
类之外的函数:
int someFunction(double *arr);
此调用工作正常:
int status;
status = someFunction(I1->retGrid()); // Properly working function call
但这并没有
status = someFunction(&I2.retGrid()); // Compiler gives error that says "error: invalid lvalue in unary &"
如果我这样称呼someFunction
:
status = someFunction(I2.retGrid()); // Compiler gives no error but function returns error value in status
代码编译,但我收到运行时错误(someFunction
内另一个函数调用的状态值错误)。
如何正确地将I2
传递给someFunction
?
非常感谢...
您正在尝试获取retGrid
返回的临时对象的地址(在本例中为指针,但这并不重要)。因此,您不能使用&
方法。
如果没有 & 符号,您将内部数组从 I2
传递到 someFunction
。如果这对您来说不合适(即因为您遇到某种运行时错误),请考虑复制此数组并将其传递给someFunction
。
当您的类中有指针并且必须为每个对象分配内存时,您需要定义复制构造函数和赋值运算符。您只添加了后者。此初始化
someClass<double> I2 = *I1;
实际上是使用复制构造函数执行的,而不是使用赋值运算符执行的。它与
someClass<double> I2(*I1);
但是,这是错误的,因为您只为网格分配内存。但是,如果网格已经分配(来自以前的分配),则会泄漏内存。所以它应该看起来像这样:
someClass & operator= (const someClass & rhs)
{
if (this != &rhs)
{
size_x = rhs.size_x;
size_y = rhs.size_y;
size_total = rhs.size_total;
delete [] grid;
grid = new T [size_total];
memcpy(grid, rhs.grid, size_total*sizeof(T));
}
return *this;
}
第一个问题:为什么不使用 std::vector
而不是尝试自己管理内存。 您不显示破坏者;我想你释放了那里的记忆。 但是有仍然有问题:
-
在复制构造函数中,使用
memcpy
。 这不是问题当您实例化double
时,但这可能是一个问题对于其他类型。 您应该使用std::copy
. -
如果您使用的是
std::vector
,并且retGrid
仍然需要返回一个T*
,它将是return &grid[0];
。 -
赋值运算符已损坏。 它泄漏了任何以前的内存,如果
new
失败,它将对象留在状态不一致。 (必须检查自我分配是通常是暗示出了问题。 正确的分配运算符将在更改之前执行所有可能失败的操作对象中的任何内容。 您可以搜索有关交换成语,但类似以下内容的内容也会工作:
.
SomeClass&
SomeClass<T>::operator=( SomeClass const& other )
{
T* newGrid = new T[other.size_total];
std::copy( other.grid, other.grid + other.size_total, newGrid );
delete [] grid;
size_x = other.size_x;
size_y = other.size_y;
size_total = other.size_total;
grid = newGrid;
return *this;
}
如果size_total
相等,则可能需要对此进行优化(或size_total <= other.size_total
)。
当然,如果你使用std::vector
,编译器生成赋值运算符和复制构造函数就足够了;你不必写任何东西。
有什么理由使用指针进行
I1
吗? (或者这只是一个更大背景的工件,你从中提取代码?关于
someFunction( &I2.retGrid() );
,someClass::retGrid()
返回一个指针。 无论是否通过指针或对象调用函数。 服用该地址会导致T**
。关于最后一个电话,没有什么会导致您向我们展示的代码中存在问题。 只要
I2
在范围内并且没有删除它的对象,应该没有问题。 这是在对象。 代码中的问题出在其他地方。
我不确定您收到的运行时错误status = someFunction(&I2.retGrid());
但正在传递指向临时对象的指针。
运行时错误可能是因为缺少在 someClass<double> I2 = *I1;
中调用的复制构造函数
感谢大家的非常有用的评论,特别是AAT,David Rodriguez - dribeas,James Kanze和Marius Bancila的评论。
事实证明,问题是与someFunction
内部第三方功能的接口不正确。我在睡眠后发现并修复了错误,现在打电话:
status = someFunction(I2.retGrid()); // Compiler gives no error but function returns error value in status
工作正常。
但是这个讨论揭示了其他非常重要的相关问题,即与我的复制构造函数和赋值运算符相关的内存管理问题,以及建议使用向量。我相信这个线程在这些优点上有很大的价值。
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法