квалификатор const для строкового литерала - PullRequest
0 голосов
/ 18 февраля 2011

У меня есть следующий код, который я написал для проверки функции-члена const: Он компилируется и работает нормально, когда у меня есть const квалификатор для члена данных char * data и аргумент для конструктора. Однако, если я удаляю const из член данных и конструктор, я получаю ошибку компилятора. Это потому, что строка «Hello World» всегда имеет тип const char *?

#include <iostream>
#include <string.h>

using namespace std;

class mystring {
        const char *data;
        mutable int length;
        mutable int valid;
public:
        mystring(const char *str) {data = str;}
        ~mystring() { };
        int GetLength() const;
};

int mystring::GetLength() const
{
        if (valid)
                return length;
        else {
                length = strlen(data);
                valid = 1;
                return length;
        }
}

int main()
{
        const char *str = "Hello World";

        mystring s(str);

        cout << s.GetLength() << endl;
}

Ответы [ 4 ]

3 голосов
/ 18 февраля 2011

Если вы удалите const из конструктора, он сообщит вызывающим, что он ожидает принять char* в качестве параметра и может изменить char в конце указателя.

Поскольку вы создаете mystring с const char*, компилятор вызывает ошибку, чтобы гарантировать, что ваш код выполняет то, что он ожидает.

2 голосов
/ 18 февраля 2011

Вы пытаетесь создать mystring с const char*, когда он хочет char* в качестве параметра.Вы не можете перейти от const к non const без приведения.

1 голос
/ 18 февраля 2011

Если вы удалите const из параметра конструктора и из элемента данных, код не будет скомпилирован, поскольку аргумент str, передаваемый конструктору, объявлен как const char *. Это абсолютно не имеет ничего общего с "Hello World" литералом. Вы можете инициализировать str с 0 вместо "Hello World", и код все равно не сможет скомпилироваться.

Строковый литерал "Hello World" имеет тип const char[12]. Однако языковые правила позволяют преобразовывать строковые литералы в тип char *, что означает, что если вы инициализировали свой объект как

mystring s("Hello World");

код прекрасно скомпилируется даже после того, как вы удалили const из параметра конструктора и члена данных. Но как только вы добавляете эту промежуточную переменную str в рисунок, "Hello World" становится неактуальным. Больше не имеет значения, что такое "Hello World". Только то, что str имеет значение.

1 голос
/ 18 февраля 2011

Да, строковые литералы в C ++ имеют тип const char *.

Чтобы рассматривать это как char *, вам нужно сделать const_cast<char*>(str).Это, вероятно, плохая идея - изменение строкового литерала приводит к неопределенному поведению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...