【问题标题】:How to initialize a class and then freeze its argument value如何初始化一个类然后冻结它的参数值
【发布时间】:2012-03-02 12:54:14
【问题描述】:

我有一个class String,它表示一个动态数组characters,初始化后无法更改。所以我需要对其进行初始化,然后防止对参数的进一步更改。

我该怎么做? :)

【问题讨论】:

  • 智者称这些类“不可变”
  • 这种不可改变的类叫做“不可变”

标签: c++ oop class object initialization


【解决方案1】:

你让你的会员const。然后在构造函数中进行初始化。

class String
{
   const char* const _buff;  //both the contents and the pointer are const
public:
   String (const char* buff);
};

String::String(const char* buff) : _buff(buff)
{
}

编辑:正如@ildjarn 所指出的,在使用不可变对象时要格外小心。你必须确定那是你真正需要的。您将无法在标准容器中使用它们,也无法进行逻辑复制。

【讨论】:

  • 将数据成员设为 const 很愚蠢——它使您的类不可赋值,这意味着您不能在 C++03 标准容器中使用您的类的实例。更明智的解决方案是仅提供 const 成员函数来访问所述数据成员,并使数据成员本身保持非 const。
  • 好的,谢谢,但是我怎样才能为这个类创建一个复制构造函数呢?还有一个析构函数? :)
  • @Vidak 您希望会员保持不变吗?
  • @ildjarn 仅仅因为你不能在容器中使用不可变对象并且你找不到理由拥有不可变对象并不会让它们变得愚蠢。
  • @LuchianGrigore:不可变对象通常很有意义,但您需要您的语言和库来支持它们。如果您不能在标准容器中使用它们,它们就是二等公民。在 Scala 或函数式语言中,情况并非如此。无论如何,听起来确实像 OP 要求一个不能在容器中使用的不可变类。当然,您仍然可以使用指向它们的指针容器(就像发生在引擎盖下,在函数式语言中用于大多数/所有值,以及对于不可变对象需要发生的情况)。
【解决方案2】:

innerstring 数组设置为私有常量,并且只公开get 方法。

【讨论】:

    【解决方案3】:

    希望这会有所帮助:

    #include <iostream>
    #include <cstring>
    #include <vector>
    
    class String {
    public:
    
      // Default constructor and 
      // conversion constructor
      String(const char *p = "") {
        data_ = new char[strlen(p)+1];
        strcpy(data_, p);
      }
    
    
      // copy constructor
      String(const String& rhs) {
        data_ = new char[strlen(rhs.data_)+1];
        strcpy(data_, rhs.data_);
      }
    
      ~String() {
        delete[] data_;
      }
    
      String& operator=(const String&rhs) {
        String temp(rhs);
        std::swap(temp.data_, data_);
        return *this;
      }
    
      // operator[] is the only data access, and it returns "const&"
      const char&operator[](std::size_t i) { return data_[i]; }
    
    private:
      char *data_;
    };
    
    
    
    int main () {
      String a("Hello");
      String b("Goodbye");
      std::vector<String> v;
    
      v.push_back("a");
      v.push_back("b");
      v.push_back(&b[4]);
    
      b = a;
    
      std::cout << &b[0] << "\n";
      std::cout << &v[2][0] << "\n";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2011-08-05
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      • 2017-10-14
      • 1970-01-01
      相关资源
      最近更新 更多