1. 程式人生 > >自定義類過載運算子出現的一堆問題

自定義類過載運算子出現的一堆問題

今天我在自定義類過載運算子<<時遇到了一個很奇怪的報錯......

先上最後能夠正常執行的程式碼吧(相關標頭檔案在stdafx.h裡面,懶得打了)

// point.h

class point
{
public:
	point(int x, int y);

	string printPos(); // "[3,5]"
	friend ostream &operator<<(ostream &os, const point &p); // [3,5]

private:
	int X, Y;
};

// point.cpp

#include "stdafx.h"
#include "point.h"

point::point(int x, int y)
{
	X = x;
	Y = y;
}

string point::printPos() // "[3,5]"
{
	return "[" + to_string(X) + "," + to_string(Y) + "]";
}


ostream &operator<<(ostream &os, const point &p) // [3,5]
{
	os << "[" + to_string(p.X) + "," + to_string(p.Y) + "]" << endl;
	return os;
}

// ConsoleApplication2.cpp

#include "stdafx.h"
#include "point.h"

int main()
{
	point p(3, 5);
	cout << p;
    return 0;
}

是一個很簡單的過載<<運算子的函式,但是我是看部落格照貓畫虎搞下來的。

friend,&,const這些大概有什麼用我理解,但是具體為什麼這麼寫我不是很清楚。所以不理解後續的各種問題。

(1)刪掉const就報錯。

error C2248: “point::X”: 無法訪問 private 成員(在“point”類中宣告)

error C2248: “point::Y”: 無法訪問 private 成員(在“point”類中宣告)

喵喵喵?上面的to_string(X) 可以直接訪問X,這裡就不可以了?就算不可以,為啥加了一個const就可以了?

看著p.覺得有點多餘,刪掉看看。

(2)刪掉p.加不加const都報錯

error C2065: “X”: 未宣告的識別符號

error C2065: “Y”: 未宣告的識別符號

果然還是報錯,但是還是不明白為什麼不可以直接訪問。

話說我幹嘛一定要刪掉const?因為我最最開始打算這樣寫的......

ostream &operator<<(ostream &os, const point &p) // [3,5]
{
	os << p.printPos() << endl;
	return os;
}

報錯:error C2662: “std::string point::printPos(void)”: 不能將“this”指標從“const point”轉換為“point &”

(誒?這個const不一樣有什麼關係麼?)

好吧,有關係就有關係吧,那我刪掉上面程式碼的const看看?那不是就型別一樣的嗎?

於是......


一臉懵逼......這是什麼錯誤???MSDN的解釋我大概看得懂,但是不明白和我有啥關係,摔!

https://docs.microsoft.com/zh-cn/cpp/error-messages/tool-errors/linker-tools-error-lnk2019?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DZH-CN%26k%3Dk(LNK2019)%26rd%3Dtrue

當然,改寫成最開頭的形式(不要嘗試在裡面呼叫p)就不會有這麼多問題了。但是這到底是什麼問題啊,好煩。

還有一個神奇的事情......如果我把函式直接寫在point.h的檔案裡時,直接刪掉const就可以正常運行了。

class point
{
public:
	point(int x, int y);

	string printPos(); // "[3,5]"
	friend ostream &operator<<(ostream &os, const point &p); // [3,5]

private:
	int X, Y;
};

point::point(int x, int y)
{
	X = x;
	Y = y;
}

string point::printPos() // "[3,5]"
{
	return "[" + to_string(X) + "," + to_string(Y) + "]";
}


ostream &operator<<(ostream &os, point &p) // [3,5]
{
	os << p.printPos() << endl;
	return os;
}

喵喵喵???為什麼???

(不出意外的,下面這種寫法也是可以的......當然把整個point.h裡面的函式都複製到main函式的檔案裡也是可以的)

class point
{
public:
	point(int x, int y)
	{
		X = x;
		Y = y;
	}

	string printPos() // "[3,5]"
	{
		return "[" + to_string(X) + "," + to_string(Y) + "]";
	}

	friend ostream &operator<<(ostream &os, point &p) // [3,5]
	{
		os << p.printPos() << endl;
		return os;
	}

private:
	int X, Y;
};
所以到底是為什麼嘛......orz

————————————————————————

剛剛發文的時候不知道為什麼,只要在標題欄輸入<<就發不了,果然是一堆問題

————————————————————————

媽耶,突然想起來!

我在刪point.cpp裡面函式的const的時候忘記把point.h裡面的const一起刪掉了......

難怪無法解析......一起都刪掉就沒什麼毛病了。(雖然按道理來說最好別刪...)

我大概就是這麼傻......

可是為什麼......

上面我把函式直接寫在point.h的檔案裡時,直接刪掉const就可以正常運行了。

喵喵喵???