gpt4 book ai didi

c++ - 结合声明和初始化与重载 `=`

转载 作者:行者123 更新时间:2023-11-28 07:08:33 25 4
gpt4 key购买 nike

我是 C++ 的新手(但不是编程的新手——我对 Java 非常了解),所以这可能有一个简单的答案,我只是忽略了。

Question in a nutshell: What (if anything) is the difference between writing:

classType a = b;

and writing

classType a;
a = b;

specifically when b is a reference variable in a function and when = is overloaded?

细节/背景:

我正在开发一个自定义的 vect 类,它(最终)将包含 n 元组,其行为类似于 R^n 中的 vector (即,数学-样式 vector ,而不是 STL 样式 vector )。因此,我重载了 = 运算符以将组件从 rhs 复制到 lhs

但是,我发现,当我的 rhs 是函数中的引用变量时,组合的声明/初始化使 rhs 和 lhs 引用相同的对象 ,而单独的初始化将它们保持为不同的对象

在我下面的程序中,这被证明为 v2 = v1 * 10 导致 v2v1 被设置为等于 v1*10 当我使用单行 vect a = b 时,但当我写 vect a; 时表现符合预期; a=b* 的定义中。

最小可编译示例:

对于它的长度,我深表歉意,但我已经尽可能地减少了它的长度。我会继续寻找减少的方法。

问题出现在* 运算符的重载中。我在那里评论了需要进行哪些更改才能显示该问题。

#include<iostream>
#include<string.h> //For toString method
#include<sstream> //For toString method

//===================================================
// Namespace for organization
namespace linalg {
class vect {
private:
//int length;
double* baseArray;
public:
//Constructor
vect() { baseArray = new double[3]; }

//TODO: Change so edits to arrayArg do not show up in the baseArray.
vect(double arrayArg[3]) { baseArray = arrayArg; }

//Returns a string for printing
std::string toString();

//Returns the element at given index
double getElementAt(int) const;

//Operator overloading:
vect& operator=(const vect &rhs);
friend vect operator*(double num, const vect &v);
};

//===================================================
// General Methods
// elementAt : return s the given element.
double vect::getElementAt(int i) const {
return baseArray[i];
}

// toString : behaves like Java convention:
//toString : gives string representation
std::string vect::toString() {
std::string retVal;

retVal.append("[");
for (int i = 0; i < 3; i++) {
//Convert the number to a string
std::ostringstream num;
num << baseArray[i];

//Append the number to the return value
retVal.append(num.str());

//Comma separated
if (i < 3-1) retVal.append(", ");
}
retVal.append("]");

return retVal;
}

//===================================================
// Operator overloads
//Overload '=' : copies the other vector into this vector
vect& vect::operator= (const vect &rhs) {
//Check for self-assignment:
if (this == &rhs) {
return *this;
}

//Copy the rhs into this vector
for (int i = 0; i < 3; i++) {
baseArray[i] = rhs.getElementAt(i);
}

return *this;
}

//Overload scalar multiplication
vect linalg::operator*(double num, const vect &v) {
//CHANGE THIS to a single-line assignment/initialization, and the problem occurs.
vect result;
result = v;

for(int i = 0; i < 3; i++) {
result.baseArray[i] *= num;
}

return result;
}
};

using namespace linalg;
using namespace std;

int main() {
double a[3] = {2, 4, 8};
double b[3] = {5, 1, 9};

vect v1(a);
vect v2(b);

v1 = 10*v2;

cout << v1.toString() << endl;
cout << v2.toString() << endl;

system("pause"); //Pause the windows terminal

return 0;
}

最佳答案

区别在于 vect a = b; 执行复制初始化vect a; a = b; 执行复制赋值。复制初始化调用复制构造函数,而复制赋值调用重载的operator=

在您的代码中,您的复制赋值运算符将一个 vector 的元素复制到另一个 vector 中,这很好。但是,您的复制构造函数只是将 LHS 的 baseArray 设置为指向与 RHS 相同的内存块,而不复制任何 vector 元素。当两个指针指向同一个内存时,当然修改一个也会修改另一个。

关于c++ - 结合声明和初始化与重载 `=`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21395353/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com