ISO C++ forbids converting a string constant to 'char*'

149
13 июня 2019, 19:40

Создал класс Human. Прототипы методов get() и set() объявил в Human.h. Human.cpp с реализацией функций тоже есть. Вот часть класса:

void Human::setFirst_name(char* first_name){
    First_name = first_name;
}
char* Human::getFirst_name(){
    return First_name;
}

В файле main.cpp заполнил поле, вот так:

first_h.setFirst_name("Василий");

Выдает предупреждение. Как избавиться?

Human.cpp

 #include <iostream>
 #include <cmath>
 #include <clocale>
 #include <cstring>
 #include <ctime>
 #include <cstdlib>
 #include "Human.h"

namespace Myspace{
Human::Human(void) {
}
~Human::Human(void) {
}
void Human::setFirst_name(const char* first_name){  
First_name = first_name;
}
const char* Human::getFirst_name() const {
return First_name;
} 

Human.h

   #pragma once
   namespace Myspace{
typedef unsigned int ui;
class Human{
private:
    const char * First_name;
    char * Patronymic;
    char * Last_name;
    ui Date_of_birth;
    ui Age;
    bool Sex;
public:
    void setFirst_name(char*);
    char* getFirst_name();
    void setPatronymic(char*);
    char* getPatronymic();
    void setLast_name(char*);
    char* getLast_name();
    ui getDate_of_birth();
    void setDate_of_birth(ui);
    ui getAge();
    void setAge(ui);
    bool getSex();
    void setSex(ui);
};
};

main.cpp

#include <iostream>
#include <cmath>
#include <windows.h>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include "Human.h"
using namespace std;
using Myspace::Human;
 int main (void){
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
  Human first_h;
   first_h.setFirst_name("Василий");
}
Answer 1

Надо не просто избавляться от предупреждений, а понимать, откуда они и что означают, и как изменить свое решение.

Строковый литерал - это по стандарту константный массив, который не может быть изменен. У вас же он передается как изменяемый, так что вы в вашей функции можете его изменять - а это недопустимо.

Вы можете использовать, например, const char * или скопировать передаваемую строку в свой объект - но как именно поступить, зависит от дизайна вашего класса - планируете ли вы владение строкой, или она всегда должна быть где-то "снаружи" (и тогда ее время жизни должно быть больше времени жизни соответствующего объекта).

Answer 2

Дело в том, что указатель на строку "Василий" является константой. Необходимо добавить ключевое слово const.

void Human::setFirst_name(const char* first_name){
    First_name = first_name;
}
const char* Human::getFirst_name(){
    return First_name;
}
Answer 3

Как избавиться?

Старательным соблюдением правил константной корректности. Если вы не собираетесь модифицировать данные через указатель, то этот указатель должен быть указателем на константу. В данном случае

void Human::setFirst_name(const char* first_name){  
    First_name = first_name;
}
const char* Human::getFirst_name() const {
    return First_name;
}

Однако это означает, что и First_name тоже должно стать const char*. А устраивает ли это вас - из того что вы привели не видно. И это отдельная тема для размышлений: что вы хотите хранить в своем классе. Указатель на внешнюю строку? Указатель на "свою" строку?

READ ALSO
Получить значений jtable зная строку

Получить значений jtable зная строку

есть ли какой-нибудь способ получить значение колонок на определенной строке зная её?

133
Добавление элементов в TreeSet

Добавление элементов в TreeSet

Использую коллекцию TreeSetВозможно добавить не больше одной записи в add

266
падает база с различными ошибками

падает база с различными ошибками

проблема в следующем-мне нужно два метода один запрос в базу без возращения Resultset,второй с возвращениемоба эти метода постоянно используются...

126