Ошибка компиляции кода из книги Р.Лафоре

86
03 августа 2019, 18:10

Учу язык С++ по книги Р.Лафоре "Объектно-ориентированное программирование на С++". Часто замечал, что некоторый код, который написан в книге, не компилируется в 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;
}

просто не компилируется, вызывая следующие ошибки:

  1. E0415 не существует подходящего конструктора для преобразования из "const char [11]" в "ClassString**"

  2. 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.**

  3. C2440 инициализация: невозможно преобразовать "const char [11]" в "ClassString"**

Код скопирован полностью слово в слово, изменены лишь название переменных. Неужели автор книги схалтурил? Или проблемы выражены у меня? Ведь точно такой же код без проблем компилируется в онлайн-компиляторах.

Каким образом мне поступить, чтобы решить эту проблему, в частности: что нужно сделать, чтобы код, который я написал, компилировался верно, согласно книги?

Answer 1

Да, этот код является нерабочим. Строковый литерал является массивом char const и его нельзя передать в функцию, принимающую указатель на char (не const). Чтобы исправить достаточно дописать:

ClassString(char const * s)

а еще лучше сделать и сам указатель константным - ведь внутри конструктора он не меняется:

ClassString(char const * const s)

Что касается онлайн компиляторов, то там зачастую в качестве компилятора выступает gcc, который имеет нестандартное расширение, допускающее такое преобразование.

А проблема с strcpy вызвана настройками проекта. VC++ по-умолчанию ругается на все "недостаточно безопасные" функции из C, хотя такой код полностью соответствует стандарту. Для исправления достаточно последовать совету, изложенному в сообщении об ошибке.

Answer 2

Книга была написана давно, тогда, когда в языке С++ действовали стандарты C++98 или С++03, в которых разрешалось преобразование строковых литералов к типу char *. Но даже там оно являлось deprecated, и за его использование всяким Лафоре следовало бы давать по рукам.

Это преобразование было навсегда удалено из языка в стандарте С++11.

Поэтому чтобы компилировать код из этой книги вам придется использовать компилятор, работающий в режиме C++03 или ранее (или переводить современный компилятор в этот режим).

В Visual Studio 2017 нет полноценного ключа, переводящего компилятор в режим C++98 или C++03. Но разрешить требуемое устаревшее преобразование можно либо огульно, переведя настройку проекта C/C++:Language:Conformance Mode в положение No, либо более целенаправленно, указав в командной строке компилятора настройку /Zc:strictStrings-.

READ ALSO
Базовый класс Array и производные классы SortArray и XorArray

Базовый класс Array и производные классы SortArray и XorArray

Помогите закончить программу пожалуйстаНеобходимо создать базовый класс Array с виртуальными методами сложения и поэлементной обработки...

129