在 C++ 中,您可以在堆和堆栈上创建类的新实例。重载运算符时,您能否以有意义的方式在堆栈上实例化?
据我了解,一旦函数执行完毕,位于堆栈上的实例就会被删除。这使得返回一个位于堆栈上的新实例看起来似乎是一个问题。
我写这篇文章时知道一定有办法,但我不确定最佳做法是什么。 如果我有一些设计为始终驻留在堆栈中的类,我该如何处理运算符重载?
任何信息都会有帮助,谢谢
{编辑} 我正在重载 + 运算符。 现在我使用这段代码
Point Point::operator+ (Point a)
{
Point *c = new Point(this->x+a.x,this->y+ a.y);
return *c;
}
我对像这样实例化 c 持怀疑态度:
Point c(this->x + a.x, this->y, a.y);
因为那会把它分配到栈上。我担心的是,一旦该函数执行完毕,堆栈指针就会发生变化,并且该实例将不再安全,因为定义的任何新局部变量都可能将其删除。这不是问题吗?
最佳答案
如果您正在谈论例如 operator+
,其中返回的对象不是这些输入中的任何一个,那么答案是您在堆栈上实例化并按值返回:
struct SomeClass {
int value;
};
SomeClass operator+(const SomeClass &lhs, const SomeClass &rhs) {
SomeClass retval;
retval.value = lhs.value + rhs.value;
return retval;
}
或
class SomeClass {
int value;
public:
SomeClass operator+(const SomeClass &rhs) const {
SomeClass retval;
retval.value = this->value + rhs.value;
return retval;
}
};
甚至:
class SomeClass {
int value;
public:
SomeClass(int v) : value(v) {}
friend SomeClass operator+(const SomeClass &lhs, const SomeClass &rhs) {
return SomeClass(lhs.value + rhs.value);
}
};
然后编译器会担心返回值实际存储在哪里(在堆栈上)。
例如,如果可以的话,它会应用返回值优化,但原则上发生的事情是“好像”你所做的工作在你的运算符重载的堆栈上构造了一些值,然后在返回时将它复制到下一个需要的地方。如果调用者分配了返回值,它会被复制到那里。如果调用者将它按值传递给其他函数,则它会被复制到调用约定要求它成为该函数参数的任何地方。如果调用者采用 const 引用,那么它会被复制到一个隐藏在堆栈中的临时位置。
关于C++运算符重载内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1449525/