我是C++的新手(但對編程並不陌生 - 我非常瞭解Java),所以這可能只是一個簡單的答案,我只能忽略它。結合聲明和初始化重載`=`
問題一言以蔽之:什麼(如果有的話)是寫作的區別是:
classType a = b;
,寫
classType a; a = b;
特別是當
b
是一個參考變量的函數當=
超載?
詳細信息/背景:
我工作的一個自定義vect
類,這將(最終)持有正元組表現得像R^n
向量(即數學式載體,不是STL風格的向量)。因此,我已經超載了=
運營商,將組件從rhs
複製到lhs
。
然而,我發現,當我RHS是一個函數的引用變量,聯合聲明/初始化使RHS和LHS引用同一對象,而單獨的初始化讓他們爲不同的物體。
在下面我的程序,這是證明爲v2 = v1 * 10
結果按v2
和v1
被設置爲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;
}
問題:你爲什麼動態分配'baseArray'?如果它總是3,你不需要(你應該使用'std :: array'。如果它的大小不同,你應該將指針存儲在'std :: unique_ptr '或使用'std :: vector ' –
Borgleader
@Borgleader我最終想把它變成一個可變長度的數組,但認爲最好先用一個固定長度的例子(爲了簡單起見)。我猜測C++處理動態大小的數組類似於Java,但顯然情況並非如此(tl; dr:我試圖使它容易擴展到長度爲n的數組,但看起來我沒有這樣做)':)' – apnorton
好吧,但你正在做額外的工作(即:自己管理記憶)。通過使用矢量,您可以擁有相同的功能,而無需處理內存管理。 (你也可以使用模板)。 – Borgleader