Я пытаюсь использовать func afficherEtat, используя имя объекта, которое ввел пользователь:
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
Персонаж.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;
}
Я пытаюсь разрешить пользователю создавать несколько Personnage, используя класс Personnage. Я не знаю заранее, сколько он создаст или их название. Я помещаю имя, которое он ввел в вектор. Теперь мне нужно вызвать метод afficherEtat, используя введенное пользователем имя. Я получаю его из вектора и помещаю в переменную, которую я использую для вызова метода из класса Personnage.
Если я создаю объект с именем, которое я выбираю сам в main(), он работает, как david.afficherEtat(); Но с пользовательским вводом и переменной это не так.
Ошибка, которую я получаю при компиляции:
error: 'std::__cxx11::string {aka class std::__cxx11::basic_string<char>}' has no member named 'afficherEtat'|
Обновлено: РАБОЧИЙ КОД
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;
}
Я не менял Personnage.cpp или Personnage.hpp
Невозможно изменить имена функций или переменных во время выполнения. Вы не можете «создать» переменную с именем Дэвид, а затем с именем Мэри. Вы можете только изменить значения. Вам нужно преобразовать вектор в People, если вы хотите вызвать функцию, иначе она будет вызываться в строке, отсюда и ошибка.
Компилятор прав. Вы вызываете функцию, определенную в Personnage
, но на string
. Проблема в вашем дизайне. Не составляйте список имен, составьте список людей.
Я думаю, вы неправильно понимаете, что делает код. Когда вы вводите имя человека, это переменная внутри класса, а не имя переменной.
Personnage(nomPerso);
не добавляет переменную с именем David
типа Personnage
. Он вызывает конструктор и присваивает имя David
новому временному экземпляру Personnage
. Вы можете изменить значение переменных во время выполнения, а не их имя. Если у вас есть переменная с именем sum_of_numbers
, вы не можете волшебным образом изменить ее на blah_blah_numbers
внутри кода. Вы не можете сделать это ни на одном языке.
Если вы хотите перечислить все имена, которые человек ввел через человека, вы можете сделать следующее:
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;
}
Хорошо, теперь немного о вашем коде:
Поскольку вы включили <string> в заголовок, нет необходимости делать это в cpp, если вы также включите заголовок, содержащий строку (в вашем случае Personnage.hpp
)
затем всегда сначала включайте заголовки stdlib, затем любые связанные с ОС и, наконец, ваши; не смешивай и не сочетай
nombrePerso
не имеет значения; просто используйте tableauNomPerso.size()
Теперь немного о моем коде:
при работе с объектами и хранении любых данных о них всегда смотрите, нужны ли вам данные или сами объекты; если бы вы отображали только имя, то да, vector<string>
было бы хорошо, но так как вы хотели также вызвать функцию, то вместо этого вам нужен был объект
при работе с объектами нужно создавать их экземпляры с помощью new
; это выделяет память, необходимую для класса, а также выполняет все вызовы инициализации; когда объект больше не нужен, его нужно удалить с помощью delete
; это освобождает память после вызова деструктора; Я использовал здесь статическую инициализацию, так как все это было сделано в той же области и для упрощения, но обычно вам нужно new
их и не забыть delete
их, когда программа завершается.
// new temp person
абсолютно не нужен и не оптимален.
нет необходимости делать это в cpp, это не очень хороший совет. Заголовочный файл можно изменить, тогда как исходные файлы могут продолжать использовать строки.
всегда сначала включать заголовки stdlib, также не рекомендуется. Первый #include должен быть заголовочным файлом, объявления которого реализованы в текущем исходном файле. После этого вы правы.
Использование new
и delete
— плохой совет. Вы не используете их в ответе, почему вы их предлагаете?
1. // новый временщик - это не так, но его код не оптимизирован и смысл был не в оптимизации, а в адаптации; Я не пытаюсь изобретать велосипед, просто исправляю его код; 2. "нет необходимости делать это в cpp" - я не обобщаю, я говорю только об этом контексте, и в этом случае это правильно, если только вы не можете перенаправить объявление std::string (что вы не можете, и вы знать это); 3. обычно да, но в зависимости от того, что вы включаете в заголовки, я обнаружил, что уменьшу намного больше конфликтов, если позволю «системе» сначала получить то, что ей нужно;
4. почему new
и delete
плохой совет? Вот как вы используете объекты, и вы также это знаете, иначе вы получите всю проблему «вне области действия». Я не использую их, да, но я уверен, что он может прочитать о новых и удалить, поэтому я не включил это в код. Извините, но я не уверен, что вы правильно используете "плохой совет". Вы можете опубликовать свой собственный ответ, если вы не согласны с моим.
Мне пришлось адаптировать некоторые детали, но это сработало! Однако, когда я запустил программу, у меня был желаемый результат в консоли, а также множество случайных символов, отличных от ascii. Я ничего не менял и перезапускал ее, и она творила чудеса. Вы знаете, почему он сделал это и решил сам?
Вы можете хотеть
vector<Personnage> tableauNomPerso;
иtableauNomPerso.emplace_back(nomPerso);
вместоpush_back