![](/img/trans.png)
[英]Do non const internal members of class become const when I have const ref to an object of that class?
[英]How do I assign a data object with const members?
希望這不是重復的。 如果是這樣,請在評論中將其指向我,我將再次刪除該問題。
我有一個數據對象,其數據僅在捆綁包中有效-即,在不使另一個成員無效的情況下更改一個成員的值是沒有意義的。
此數據對象描述了一些圖像信息:
struct ImageInfo
{
ImageInfo(const double &ppix, ...)
: PpiX(ppix),
...
{ }
const double PpiX;
const double PpiY;
const int SizeX;
const int SizeY;
};
在我的圖像對象中,我具有ImageInfo
類型的非常量成員:
class MyImageObject
{
...
private:
ImageInfo mMyInfo;
}
我希望能夠在運行時更改mMyInfo
,但這只是為了使其采用新的ImageInfo(...)實例。
在MyImageObject::Load()
函數中,我想從文件信息中讀取此數據,然后使用正確的數據集創建一個ImageInfo
實例:
double ppix = ImageFile.GetPpiX();
...
mMyInfo = ImageInfo(ppix, ...);
但是我無法編寫一個有效的賦值運算符(當然可以使用復制構造函數)。 我的解決方案將mMyInfo
空,因為我沒有引用this
:
ImageInfo operator=(const ImageInfo &other)
{
// no reference to *this
return ImageInfo(other);
}
出於好奇,我想知道此類的賦值運算符的外觀。
我正在使用純C ++。
編輯
可能的解決方案(目標是保持數據可傳輸,但保持一致):
Get...()
函數一起使用->簡單,但我想避免使用括號。 ImageInfo *mpMyInfo;
的指針: ImageInfo *mpMyInfo;
(我想避免堆。) 我認為您不能擁有非靜態的const成員變量。 如果需要隨實例更改的const變量,則可以執行以下操作:
struct ImageInfo
{
private:
double myPpiX;
double myPpiY;
int mySizeX;
int mySizeY
public:
ImageInfo(const double &ppix, ...)
: myPpiX(ppix),
PpiX(myPpiX),
...
{ }
ImageInfo( const ImageInfo &other)
: myPpiX( other.myPpiX),
PpiX(myPpiX)
...
{ }
const double &PpiX;
const double &PpiY;
const int &SizeX;
const int &SizeY;
// EDIT: explicit assignment operator was missing
ImageInfo& operator=(const ImageInfo &other)
{
myPpiX = other.myPpiX;
myPpiY = other.myPpiX;
mySizeX = other.mySizeX;
mySizeX = other.mySizeX;
return *this;
}
};
這些值存儲在可在構造時設置的私有變量中,並且它們的值可通過const引用進行訪問。 只要ImageInfo實例存在,您也不依賴傳遞給構造函數的引用。
因為它們是可以修改的數據字段,所以它們不是const
。
如果要const
它們的構造后訪問限制為const
,則需要將它們包裝在訪問器中,如下所示:
struct ImageInfo
{
ImageInfo(const double &ppix, /*...*/)
: PpiX_(ppix),
/*...*/
{ }
double const& PpiX() const {return PpiX_; };
double const& PpiY() const {return PipY_; };
int const& SizeX() const {return SizeX_; };
int const& SizeY() const {return SizeY_; };
private:
double PpiX_;
double PpiY_;
int SizeX_;
int SizeY_;
};
這使得移動/復制分配和建設,同時阻止非const
訪問以外的建說。
避免使用()
很棘手,但是可以使用偽引用來完成,如下所示:
struct pseudo_const_reference_to_Ppix {
ImageInfo const* self;
operator double() const { return self->Ppix; }
void reseat( ImageInfo const* o ) { self = o; }
};
加上一堆樣板來重載左右的每個const
運算符,使得上面的pseudo_const_reference_*
與double
一樣有效。
可以編寫通用版本(如果您願意承擔類型擦除的開銷,則可以使用函子或std::function
)。
然后,您可以在分配和復制/移動構造時維護這些偽const
引用。
我認為()
是更好的選擇。
請注意,每個偽引用的指針(或多個指針)的開銷基本上是不可避免的:成員變量無法訪問從中調用它們的this
,即使訪問站點當天將訪問該變量的位置也很簡單。
如果某些內容為const,則無法更改。 句號
因此,您必須在某個地方調整設計,要么不具有那些ImageInfo成員const,不具有ImageInfo作為成員,要么最好:不進行分配。
通常const成員是在構造函數中設置的。 您可以創建一個加載函數,以創建一個包含所有內容的MyImageObject對象,這樣就避免了事半功倍並在第二階段加載狀態。
一種替代方法是間接使用mMyInfo,例如使用unique_ptr,然后可以將其替換為另一個實例。 如果沒有充分的理由,我不會這樣做。
不可變的價值對象很棒。 但是保存值對象(MyImageObject中的mMyInfo)的變量應該是(非常數)指針。 在其他語言(例如Java)中,這是自動的情況,但在C ++中則不是這樣,您需要*運算符。 同樣,也不需要為值對象重寫/實現=運算符。 要更改圖像對象內的圖像數據,請將新構造的ImageInfo對象分配給myImageInfo指針。 這樣,值對象的內部變量都不會更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.