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!
Declaring a member function with the const keyword specifies that the function is a "read-only" function that doesn't modify the object for which it's called. A constant member function can't modify any non-static data members or call any member functions that aren't constant.
A function becomes const when the const keyword is used in the function's declaration. The idea of const functions is not to allow them to modify the object on which they are called. It is recommended the practice to make as many functions const as possible so that accidental changes to objects are avoided.
The const means that the method promises not to alter any members of the class. You'd be able to execute the object's members that are so marked, even if the object itself were marked const : const foobar fb; fb.
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.
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.
You should use std::
in the class declaration. See Why is “using namespace std;” considered bad practice? on the question why.
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
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);
.
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).
A 'blank' default value for a std::string
is an empty string like
std::string const & id = std::string{}
Appears clearer to me.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With