簡體   English   中英

用 const 成員替換某個類型的變量

[英]Replace a variable of a type with const members

假設我有一個帶有一些常量成員的類:

class MyClass {
public:
   MyClass(int a) : a(a) {
   }
   MyClass() : MyClass(0) {
   }
   ~MyClass() {
   }
   const int a;
};

現在我想在某處存儲MyClass的實例,例如作為全局變量或作為另一個對象的屬性。

MyClass var;

后來,我想給var賦值:

var = MyClass(5);

顯然,這行不通,因為調用了賦值運算符,默認情況下不存在,因為MyClass有一個 const 屬性。 到現在為止還挺好。

我的問題是,無論如何我如何為var賦值? 畢竟, var本身並沒有被聲明為常量。

到目前為止我的想法

我知道如果我對var使用指針,則問題不存在:

MyClass *var;
var = new MyClass(5);

但是,出於方便的原因,我不想使用指針。

一個潛在的解決方案是用placement new 覆蓋內存:

template<class T, class... Args>
T &emplaceVar(T &myVar, Args&&... args) {
   myVar.~T(); // free internal memory
   return *new (&myVar) T(args...);
}

emplaceVar(var, 5);

這將解決問題,但我不確定這是否會導致內存泄漏或由於我缺乏 C++ 經驗而沒有想到的任何其他問題。 此外,我會認為必須有一種更簡單的方法。 有沒有?

由於您發現的原因, const成員通常有問題。

更簡單的選擇是將成員設為private並注意不要提供從類外部修改它的方法:

class MyClass {
public:
   MyClass(int a) : a(a) {
   }
   MyClass() : MyClass(0) {
   }
   ~MyClass() {
   }
private:
   int a;
};

我還沒有添加 getter,因為你說通過myObject.a訪問是一個硬性要求。 啟用它需要一些樣板文件,但它比修改一些不能修改的東西要少得多:

class MyClass {
public:
   struct property {
       const int& value;
       operator int(){ return value;}
       property(const property&) = delete;
   };

   MyClass(int a = 0) : value(a) {}
private:
   int value;
public:
    property a{value};
};

int main(){
    MyClass myObject{5};
    int x = myObject.a;
    //myObject.a = 42; // error
    //auto y = myObject.a; // unexpected type :/
}

現場演示

缺點是它不能很好地與auto 如果您可以通過任何方式接受myObject.a()我建議使用它並保持簡單。

無論如何,我如何為 var 賦值?

您可以使用用戶定義的賦值運算符來做到這一點:

class MyClass {
public:
   MyClass &operator=(const MyClass &o)
   {
         // Implement your assignment here

         return *this;
   }

   // ...
};

您的賦值運算符可以做任何operator=重載可以做的事情。 它唯一不能做的就是為它的const類成員分配任何東西。 那是因為它是恆定的。

如果一個類沒有用戶定義的賦值運算符,則默認賦值運算符從被賦值對象的同一成員中分配被賦值對象的每個成員。 然而,默認賦值運算符會從任何具有const成員的類中刪除,因為這當然不再可能。

在您的用戶定義運算符中,您可以做任何事情來從另一個對象分配這些對象之一。 它唯一不能做的事情與任何其他類方法都不能做的事情是一樣的:修改const類成員。

您提到了析構函數的手動調用和新的放置。 這是可能的,前提是滿足所有必要的要求並且小心避免未定義的行為。 但是,從技術上講,這不是賦值,而是手動銷毀和構建另一個對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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