Home > Back-end >  How to call a method from a class, using the unknown name of an object created by that class?
How to call a method from a class, using the unknown name of an object created by that class?

Time:12-30

I'm trying to use the func afficherEtat, using the object name that the user typed in :

Personnage.hpp

#ifndef PERSONNAGE_HPP_INCLUDED
#define PERSONNAGE_HPP_INCLUDED
#include <iostream>
#include <string>
class Personnage { public: Personnage(std::string nomPerso); void afficherEtat() const; 
private: std::string m_nomPerso;    };  
#endif 

Personnage.cpp

#include "Personnage.hpp"
#include <string>
using namespace std;
Personnage::Personnage(string nomPerso) : m_nomPerso(nomPerso) {}
void Personnage::afficherEtat() const
{    cout << "Le nom : " << m_nomPerso << endl;}

main.cpp

#include <iostream>
#include <string>
#include "Personnage.hpp" 
#include <vector>

int main()
{
    string creaPersoFini("y");
    int nombrePerso(0);
    vector<string> tableauNomPerso;
    string nomPerso;

    while(creaPersoFini!="n")
    {
        cout << "Entrez le nom du personnage : ";
        cin >> nomPerso;
        tableauNomPerso.push_back(nomPerso);
        Personnage(nomPerso);
        cout << "Voulez vous creer un autre personnage ? y/n ";  
        cin >> creaPersoFini;
        nombrePerso  ;
    }

    for(int i=0; i<=nombrePerso; i  )
    {
        cout << endl;
        cout << tableauNomPerso[i] << endl;
        nomPerso = tableauNomPerso[i];
        nomPerso.afficherEtat();                // HERE IS THE PROBLEM
        cout << endl;
    }
return 0;
}

I'm trying to allow the user to create multiple Personnage, using the class Personnage. I don't know in advance how many he will create or their name. I put the name that he entered into a vector. What i need now is to call the method afficherEtat, using the name the user entered. I get it from the vector and put it into a variable, that i'm using to call the method from the class Personnage.

If i create the object with a name i choose myself in the main(), it works, like david.afficherEtat(); But with a user input and a variable it doesn't.

The error i get while compiling is:

error: 'std::__cxx11::string {aka class std::__cxx11::basic_string<char>}' has no member named 'afficherEtat'|

EDIT : WORKING CODE

int main()
{
    string creaPersoFini("y");
    vector<Personnage> tableauPerso;    // Tableau de Personnage, pas de string
    string nomPerso;

    while(creaPersoFini!="n")
    {
        cout << "Entrez le nom du personnage : ";
        cin >> nomPerso;
        Personnage newP(nomPerso);              // new temp person
        tableauPerso.push_back(newP);           // add the person
        cout << "Voulez vous creer un autre personnage ? y/n ";
        cin >> creaPersoFini;
    }

    for(int i=0; i<tableauPerso.size(); i  )        // <, pas <=, sinon ça affiche 1 vide.
    {
        cout << endl;
        tableauPerso[i].afficherEtat();
        cout << endl;
    }
return 0;
}

I didn't change Personnage.cpp or Personnage.hpp

CodePudding user response:

The compiler is right. You're calling a function defined in Personnage but on string. The problem is with your design. Don't make a list of names, make a list of people.

I think you are misunderstanding what the code does. When you enter the name of a person, that is the variable inside the class, not the name of the variable.

Personnage(nomPerso); doesn't add a variable with the name David that is of type Personnage. It calls the constructor and assigns the name David to a new temporary instance of Personnage. You can change the value of variables at run-time, not their name. If you have a variable called sum_of_numbers you can't magically change it to blah_blah_numbers inside the code. You can't do this in any language.

If you want to enumerate all names the person entered via a person, this is what you can do:

int main()
{
    string creaPersoFini("y");
    int nombrePerso(0);
    vector<Personnage> tableauPerso;  // change to people and delete the total number

    while(creaPersoFini!="n")
    {
        cout << "Entrez le nom du personnage : ";
        cin >> nomPerso;
        Personnage newP(nomPerso);        // new temp person
        tableauPerso.push_back(newP);     // add the person
        cout << "Voulez vous creer un autre personnage ? y/n ";  
        cin >> creaPersoFini;
    }

    for(int i=0; i<=tableauPerso.size(); i  )
    {
        cout << endl;
        cout << tableauPerso[i].afficherEtat() << endl;
    }
    return 0;
}

OK, now a few things about your code:

  1. Because you included <string> in the header, there is no need to do it in the cpp, if you also include the header that included string (in your case Personnage.hpp)

  2. next, always include stdlib headers first, then any OS related ones and lastly yours; don't mix and match

  3. nombrePerso is irrelevant; just use tableauNomPerso.size()

Now a few things about my code:

  1. when working with objects and storing whatever data you want about them, always see if you need the data or the objects themselves; if you would have only displayed the name, then yes, a vector<string> would have been fine, but since you wanted to also call a function, then you needed the object instead

  2. when working with objects you need to instantiate them using new; this allocates the memory needed for the class as well as performs all initialization calls; when the object is no longer needed, it needs to be removed using delete; this deallocates the memory after calling the destructor; I used static initialization here since it was all done in the same scope, and to simplify it, but normally you need to new them and to remember to delete them when the program ends

  • Related