Учу язык С++ по книги Р.Лафоре "Объектно-ориентированное программирование на С++". Часто замечал, что некоторый код, который написан в книге, не компилируется в Visual Studio 17 (как с другими версиями - не знаю).
Например, при компиляции следующий код
#include <iostream>
#include <cstring>
using namespace std;
class ClassString
{
private:
char *str;
public:
ClassString(char *s)
{
int len = strlen(s);
str = new char[len + 1];
strcpy(str, s);
}
~ClassString()
{
cout << "Удаляю строку" << endl;
delete[] str;
}
void display()
{
cout << "str: " << str << endl;
}
};
int main()
{
setlocale(LC_ALL, "Russian");
ClassString someObj = "someString";
cout << "someObj = ";
someObj.display();
system("pause");
return 0;
}
просто не компилируется, вызывая следующие ошибки:
E0415 не существует подходящего конструктора для преобразования из "const char [11]" в "ClassString**"
C4996 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.**
C2440 инициализация: невозможно преобразовать "const char [11]" в "ClassString"**
Код скопирован полностью слово в слово, изменены лишь название переменных. Неужели автор книги схалтурил? Или проблемы выражены у меня? Ведь точно такой же код без проблем компилируется в онлайн-компиляторах.
Каким образом мне поступить, чтобы решить эту проблему, в частности: что нужно сделать, чтобы код, который я написал, компилировался верно, согласно книги?
Да, этот код является нерабочим. Строковый литерал является массивом char const
и его нельзя передать в функцию, принимающую указатель на char
(не const
). Чтобы исправить достаточно дописать:
ClassString(char const * s)
а еще лучше сделать и сам указатель константным - ведь внутри конструктора он не меняется:
ClassString(char const * const s)
Что касается онлайн компиляторов, то там зачастую в качестве компилятора выступает gcc, который имеет нестандартное расширение, допускающее такое преобразование.
А проблема с strcpy
вызвана настройками проекта. VC++ по-умолчанию ругается на все "недостаточно безопасные" функции из C, хотя такой код полностью соответствует стандарту. Для исправления достаточно последовать совету, изложенному в сообщении об ошибке.
Книга была написана давно, тогда, когда в языке С++ действовали стандарты C++98 или С++03, в которых разрешалось преобразование строковых литералов к типу char *
. Но даже там оно являлось deprecated, и за его использование всяким Лафоре следовало бы давать по рукам.
Это преобразование было навсегда удалено из языка в стандарте С++11.
Поэтому чтобы компилировать код из этой книги вам придется использовать компилятор, работающий в режиме C++03 или ранее (или переводить современный компилятор в этот режим).
В Visual Studio 2017 нет полноценного ключа, переводящего компилятор в режим C++98 или C++03. Но разрешить требуемое устаревшее преобразование можно либо огульно, переведя настройку проекта C/C++:Language:Conformance Mode
в положение No
, либо более целенаправленно, указав в командной строке компилятора настройку /Zc:strictStrings-
.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
На данный вопрос уже ответили:
Помогите закончить программу пожалуйстаНеобходимо создать базовый класс Array с виртуальными методами сложения и поэлементной обработки...