簡體   English   中英

如何為數據對象分配const成員?

[英]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; (我想避免堆。)
  • 使用序列化並存儲序列化的ImageInfo,然后從序列化的數據創建本地實例。

我認為您不能擁有非靜態的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM