【问题标题】:'this' argument has type const but function is not marked const'this' 参数的类型为 const 但函数未标记为 const
【发布时间】:2015-12-07 20:21:22
【问题描述】:

好的,所以我在 C++ 方面有点菜鸟,在我的第二个作业中,我需要创建带有公共和私有参数等的类。基本上,mutator 函数不起作用,因为它们显然不是输入常量?

这是带有类的头文件:

class Customer {

private:
    string PhoneNumber_;
    string Name_;
    string Address_;

public:
    string get_PhoneNumber() const {return PhoneNumber_;} // Accessor
    const void set_PhoneNumber(unsigned x) {PhoneNumber_ = x;} // Mutator

    string get_Name() const {return Name_;}
    const void set_Name(unsigned x) {Name_ = x;}

    string get_Address() const {return Address_;}
    const void set_Address(unsigned x)  {Address_ = x;}
};

// declare the CreateCustomer function prototype with default values
Customer* CreateCustomer(const string& id = BLANK, const string& name = BLANK, const string& address = BLANK);

Customer* CreateCustomer(const string& id, const string& name, const string& address) {
    Customer* temp = new Customer();

    temp->get_PhoneNumber() = id; // Due to the Accessors and Mutators PhoneNumber, Name and Address are now functions
    temp->get_Name() = name;
    temp->get_Address() = address;

    return temp;
}

这是我在 main.cpp 文件中遇到的错误:

cout << "\n\nDear ";
    cout << Charge[0].Holder.set_Name() << " (" << Charge[0].Holder.set_PhoneNumber() << ")";  //  DisplayCustomer(customer) ;

    cout << ",\n" << Charge[0].Holder.set_Address() << "\n\n"

基本上,确切的错误信息是:

成员函数“set_Name”不可行:“this”参数的类型为“const” Customer',但函数不是 const 类型

set_PhoneNumber 和 set_Address 也会发生这种情况。任何帮助将不胜感激!谢谢!

更新:我搞定了。感谢大家帮助我!

【问题讨论】:

  • 返回类型为const void!?
  • 如果您想设置 电话号码CreateCustomer() 应该拨打set_PhoneNumber(id)。它的论点看起来需要是 string 而不是 unsigned
  • 您的错误信息是不言自明的。您不能在 const 对象上调用非常量函数。但是,我看不出什么是 Charge 或 Holder,或者您在哪里以及如何声明这些实体。
  • ChargeHolder 是什么?

标签: c++ function constants setter getter


【解决方案1】:

如果要设置值,请使用 set 方法。 get 方法仅用于获取变量,而不是设置类的内部变量(如果它们是按照您的方式定义的)。

正确的用法是:

Customer* CreateCustomer(const string& id, const string& name, const string& address) {
    Customer* temp = new Customer();

    temp->set_PhoneNumber( id );
    temp->set_Name( name );
    temp->set_Address( address );

    return temp;
}

此外,您必须更改方法的接口:

class Customer {

private:
    string PhoneNumber_;
    string Name_;
    string Address_;

public:
    string get_PhoneNumber() const {return PhoneNumber_;} // Accessor
    void set_PhoneNumber(const string& x) {PhoneNumber_ = x;} // Mutator

    string get_Name() const {return Name_;}
    void set_Name(const string& x) {Name_ = x;}

    string get_Address() const {return Address_;}
    void set_Address(const string& x)  {Address_ = x;}
};

因为你想设置字符串而不是数字。

使用const string&amp; 作为函数参数比在将字符串作为参数传递时不复制字符串要好。由于它是一个 const 引用,因此您不必担心该函数会操纵输入。

【讨论】:

    【解决方案2】:

    嗯。我认为您应该以相反的方式使用getset... 在CreateCustomer 中,您应该使用set 函数,当打印Customer 进行流式传输时 - 您应该使用get 函数。 而set 函数应该接收string,而不是unsigned

    因此,最好使用constructor,而不是set 函数,然后将只有get 函数。

    【讨论】:

    • 我认为更重要的是要提到 set 和 get 函数首先不应该存在......
    【解决方案3】:
    1. 您应该在类声明中使用std::。请参阅Why is “using namespace std;” considered bad practice? 了解为什么。

    2. 您的 set_ 方法采用 unsigned 参数。您不能将无符号分配给像PhoneNumber_ = x; 这样的字符串。参数必须是字符串。

    你需要改变你的成员喜欢

    std::string get_PhoneNumber() const { return PhoneNumber_; } // Accessor
    const void set_PhoneNumber(std::string const & x) { PhoneNumber_ = x; } // Mutator
    
    1. 当您编写temp-&gt;get_PhoneNumber() = id; 时,您的意图显然是设置 PhoneNumber_ 的值,那么为什么要使用get_ 方法呢?只需使用适当的 set_ 方法并写上temp-&gt;set_PhoneNumber(id);

    2. 在 C++ 中通常避免使用指针。如果您确实需要指针,请使用像 std::unique_ptrstd::shared_ptr 这样的智能指针(当且仅当您需要使用普通指针时:使用一个)。

    3. std::string'blank' 默认值是一个空字符串,例如

      std::string const &amp; id = std::string{} 在我看来更清晰。

    4. 要使用空白/空成员字符串创建Customer 类型的对象,您不需要做更多的事情Customer customer_object;,因为有一个隐式声明的默认构造函数使用std::string 默认构造函数导致无论如何都是空的。

    5. 通常构造函数用于根据某些参数值创建对象。

    你可以很容易地写出一个接受所有需要的值,并且无论如何都可以通过添加一些类似的东西来用作默认构造

    Customer(const std::string& id = std::string{}, 
      const std::string& name = std::string{}, 
      const std::string& address = std::string{})
      : PhoneNumber_(id), Name_(name), Address_(address)
    { }
    

    到你的班级。见另一个C++ Class Initialization List example

    查看另一个C++ Class Initialization List example

    1. 为了封装,您通常希望避免使用“direct”getter 和 setter 来显示您的数据结构。

    【讨论】:

      【解决方案4】:

      您已将 PhoneNumber_Name_Address_ 声明为 string
      但在 setter 方法中,您传递的是 unsigned (int)

      此外,您还颠倒了 getter 和 setter 的用法!

      另外,setter 的返回类型可以只是void 而不是const void

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-20
        • 2020-03-07
        • 1970-01-01
        • 2023-04-08
        • 2021-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多