'this' argument has type const but function is not marked const

60,402

Solution 1

If you want to set a value, use the set method. get Methods are only to obtain variables, not to set the inner variables of a class (If they are defined the way you did).

The correct usage is:

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;
}

Also, you have to alter the interface of your methods:

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;}
};

Since you want to set strings and not numbers.

Using const string& as function arguments is better than string to not copy the string when passing it as an argument. Since it is a const reference, you don't have to fear the function could manipulate the input.

Solution 2

Ehm. I think you should use get and set in reverse way... In CreateCustomer you should use set functions and when print Customer to stream - you should use get functions. And set functions should receives string, not unsigned.

And so, it will be better to use constructor, instead of set functions and then will be only get functions.

Solution 3

  1. You should use std:: in the class declaration. See Why is “using namespace std;” considered bad practice? on the question why.

  2. Your set_ methods take unsigned arguments. You cannot assign an unsigned to a string like PhoneNumber_ = x;. The arguments need to be strings.

You'd need to change your members like

std::string get_PhoneNumber() const { return PhoneNumber_; } // Accessor
const void set_PhoneNumber(std::string const & x) { PhoneNumber_ = x; } // Mutator
  1. When you write temp->get_PhoneNumber() = id; your intention is clearly to set the value for PhoneNumber_, so why do you use the get_ method? Just use the appropriate set_ method and write temp->set_PhoneNumber(id);.

  2. Generally avoid pointers in C++. If you're really in need of a pointer use a smart pointer like std::unique_ptr or std::shared_ptr (if and only if you are required to use a plain pointer: use one).

  3. A 'blank' default value for a std::string is an empty string like

    std::string const & id = std::string{} Appears clearer to me.

  4. To create an object of type Customer with blank/empty member strings you do not need to do more than Customer customer_object; since there is an implicitly declared default constructor which uses the std::string default constructor which results in an empty strign anyway.

  5. Usually a constructor is used to create an object depending on some arguments values.

You could easily write one that takes all required values and can be used as a default constructo anyway by adding something along the lines of

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)
{ }

to your class. See another C++ Class Initialization List example.

See another C++ Class Initialization List example.

  1. For the sake of encapsulation you usually want to avoid using 'direct' getters and setters revealing your data structure.
Share:
60,402
Admin
Author by

Admin

Updated on September 12, 2020

Comments

  • Admin
    Admin over 3 years

    Okay so I'm a bit of a noob at C++ and in my second assignment I am required to make classes with public and private arguments etc, etc. Basically the mutator functions won't work because apparently they're not of type const?

    This is the header file with the class:

    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;
    }
    

    And this is the error I get in the main.cpp file:

    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"
    

    Basically, the exact error message is:

    Member function 'set_Name' not viable: 'this' argument has type 'const Customer', but function is not type const

    It happens with set_PhoneNumber and set_Address as well. Any help would be greatly appreciated! Thanks!

    UPDATE: I got it working. Thanks everyone for helping me out!