首页 > 解决方案 > 用 const 成员替换一个类型的变量

问题描述

假设我有一个带有一些常量成员的类:

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

现在我想存储MyClass某处的实例,例如作为全局变量或作为另一个对象的属性。

MyClass var;

稍后,我想为var

var = MyClass(5);

显然,这不起作用,因为调用了assign运算符,默认情况下不存在,因为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++ 经验而没有想到的任何其他问题。此外,我原以为必须有一种更简单的方法。有没有?

标签: c++constantsvariable-assignmentassignment-operatoremplace

解决方案


const由于您发现的原因,成员通常是有问题的。

更简单的替代方法是创建成员private并注意不提供从类外部修改它的方法:

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

我还没有添加吸气剂,因为您说通过访问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(),我建议您使用它并保持简单。


推荐阅读