私はすでにこの問題の回避策を見つけましたが、私が見ている問題を引き起こすために実際に何が起こっているのか誰かが知っているかどうか疑問に思っていました。私の推測では、それは文字列の可変性と関係があると思いますが、コピーコンストラクターではCStringオブジェクトがそれを説明していると思いました。
次のコードにより、mFileNameが上書きされます。
class File {
public:
...
CString GetFilename() {return mFileName;}
private:
CString mFileName;
};
class FileContainer {
private: File* mFile;
public:
FileContainer() {
mFile = new File("C:\temp.txt");
}
GetFilename(CString& fileName) {
fileName = mFile->GetFileName();
}
}
void UpdateText() {
FileContainer fileCnt;
CString filePath(L"");
this->fileCnt.GetFilename(filePath);
...
::DrawText(hDC, filePath, -1, &destRect, DT_PATH_ELLIPSIS | DT_MODIFYSTRING | DT_CALCRECT);
}
何が起こるかというと、UpdateTextが最初に呼び出されたときに、GetFilenameはC:\temp.txtを返します。バウンディングレクが最初の呼び出しでテキストを「...\temp.txt」に切り捨てたと仮定すると、「...\temp.txt」はUpdateTextへの2回目の呼び出しでGetFilenameから返されるものです。
さらに厄介なのは、これによってmFileNameが変更されなかったことです。
void UpdateText() {
FileContainer fileCnt;
CString filePath(L"");
this->fileCnt->GetFilename(filePath);
filePath = L"TEST";
}
GetFilenameは常にC:\temp.txtを返しました。したがって、DrawText関数はどういうわけか元のCStringを見つけて、それを変更しているように見えます。しかし、どのように?
更新: mFileNameが上書きされる原因となる別の奇妙なコードチャンクをスローすると思いました:
class File {
public:
...
CString GetFilename() {return CString(mFileName);}
private:
CString mFileName;
};
新しいオブジェクトを作成し、その新しいオブジェクトを返す必要があるようです。それでも、どういうわけか、DrawTextはまだmFileNameを上書きします。
コードを次のように変更しても、問題はありません。
class File {
public:
...
CString GetFilename() {return CString(mFileName.GetBuffer());}
private:
CString mFileName;
};
問題を解決しているように見える唯一のことは、回避策で示した方法で新しいCStringを構築することです。DT_MODIFYSTRINGオプションを渡すと、DrawTextは何をしますか?