web-dev-qa-db-fra.com

'cet' argument a le type const mais la fonction n'est pas marquée const

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é!

15
Liam George

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.

5
Gombat
  1. 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.

  2. 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
  1. 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);.

  2. É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).

  3. 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.

  4. 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.

  5. 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++ .

  1. Pour des raisons d'encapsulation, vous devez généralement éviter d'utiliser des getters et setters ' direct révélant votre structure de données.
2
Pixelchemist

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.

1
ForEveR

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.

0
CinCout