D'accord, donc je suis un peu un noob en C++ et dans ma deuxième tâche, je suis obligé de faire des classes avec des arguments publics et privés, etc., etc.
Il s'agit du fichier d'en-tête avec la classe:
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;
}
Et voici l'erreur que j'obtiens dans le fichier 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"
Fondamentalement, le message d'erreur exact est:
La fonction membre 'set_Name' n'est pas viable: l'argument 'this' a le type 'const Customer', mais la fonction n'est pas de type const
Cela se produit également avec set_PhoneNumber et set_Address. Toute aide serait grandement appréciée! Merci!
MISE À JOUR: Je l'ai fait fonctionner. Merci à tous de m'avoir aidé!
Si vous souhaitez définir une valeur, utilisez la méthode set. Les méthodes get servent uniquement à obtenir des variables, pas à définir les variables internes d'une classe (si elles sont définies comme vous l'avez fait).
L'utilisation correcte est:
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;
}
De plus, vous devez modifier l'interface de vos méthodes:
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;}
};
Puisque vous voulez définir des chaînes et non des nombres.
En utilisant const string&
en tant qu'arguments de fonction vaut mieux que chaîne pour ne pas copier la chaîne lors du passage en argument. Puisqu'il s'agit d'une référence const, vous n'avez pas à craindre que la fonction puisse manipuler l'entrée.
Vous devez utiliser std::
Dans la déclaration de classe. Voir Pourquoi "utiliser l'espace de noms std;" est-il considéré comme une mauvaise pratique? sur la question pourquoi.
Vos méthodes set_
Acceptent les arguments unsigned
. Vous ne pouvez pas affecter un signe non signé à une chaîne comme PhoneNumber_ = x;
. Les arguments doivent être des chaînes.
Vous devez changer vos membres comme
std::string get_PhoneNumber() const { return PhoneNumber_; } // Accessor
const void set_PhoneNumber(std::string const & x) { PhoneNumber_ = x; } // Mutator
Lorsque vous écrivez temp->get_PhoneNumber() = id;
votre intention est clairement de définir la valeur de PhoneNumber_
, Alors pourquoi utilisez-vous le méthode get _ ? Utilisez simplement la méthode appropriée set _ et écrivez temp->set_PhoneNumber(id);
.
Évitez généralement les pointeurs en C++. Si vous avez vraiment besoin d'un pointeur, utilisez un pointeur intelligent comme std::unique_ptr
Ou std::shared_ptr
(Si et seulement si vous devez utiliser un pointeur ordinaire: utilisez-en un).
Une valeur par défaut 'vide' pour un std::string
Est une chaîne vide comme
std::string const & id = std::string{}
Semble plus clair pour moi.
Pour créer un objet de type Customer
avec des chaînes de membre vides/vides, vous n'avez pas besoin de faire plus que Customer customer_object;
Car il existe un constructeur par défaut déclaré implicitement qui utilise la valeur par défaut std::string
constructeur qui entraîne de toute façon un strign vide.
Habituellement, un constructeur est utilisé pour créer un objet en fonction de certaines valeurs d'arguments.
Vous pouvez facilement en écrire une qui prend toutes les valeurs requises et qui peut être utilisée comme construction par défaut de toute façon en ajoutant quelque chose dans le sens de
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)
{ }
à votre classe. Voir un autre exemple de liste d'initialisation de classe C++ .
Voir un autre exemple de liste d'initialisation de classe C++ .
Ehm. Je pense que vous devriez utiliser get
et set
en sens inverse ... Dans CreateCustomer
vous devez utiliser les fonctions set
et lors de l'impression Customer
pour diffuser - vous devez utiliser les fonctions get
. Et les fonctions set
devraient recevoir string
, pas unsigned
.
Et donc, il vaudra mieux utiliser les fonctions constructor
, au lieu des fonctions set
et ne seront alors que les fonctions get
.
Vous avez déclaré PhoneNumber_
, Name_
Et Address_
Comme string
.
Mais dans les méthodes de définition, vous passez unsigned (int)
De plus, vous avez inversé l'utilisation des getters et setters!
De plus, les types de retour des setters peuvent être simplement void
et non const void
.