указатель константы присваивает указателю

Почему может я не делать этого:

char* p = new char[10];

void SetString(char * const str)
{
    p = str;
}


SetString("Hello");

У меня есть указатель константы на символ, почему я не могу присвоить указатель константы на другой указатель?

Это просто кажется нелогичным, как путем присвоения его другому указателю, Вы по существу не нарушаете мыс константы символьного указателя. Или Вы?

Править: Когда я компилирую это, это говорит "ошибку C2440: '=': не может преобразовать из 'символа *константа * __ w64' для 'обугливания *'"

(Я пытаюсь понять понятие из книги, которую я читаю. Просто не может заставить код компилировать.

КОД:

int _tmain(int argc, _TCHAR* argv[])
{

    MyString *strg = new MyString(10);
    strg->SetString("Hello, ");

    MyString *secondstr = new MyString(7);
    secondstr->SetString("Tony");

    strg->concat(*secondstr, *strg);

}

ФАЙЛ CPP:

#include "MyStringClass.h"
#include <string.h>
#include "stdafx.h"

#include "MyStringClass.h"

void MyString::concat(MyString& a, MyString& b)
{
    len = a.len + b.len;
    s = new char[len + 1];
    strcpy(s, a.s);
    strcat(s, b.s);
    delete [] s; 

}

void MyString::SetString(char * const str)
{
    s = str;
}

MyString::MyString(int n)
{
    s = new char[n+1];
    s[n+1] = '\0';
    len = n;
}

ЗАГОЛОВОЧНЫЙ ФАЙЛ:

#include <string.h>
#include <stdio.h>

class MyString
{
private:
    char* s;
    int len;
public:
    MyString(int n = 80);

    void SetString (char * const str);

    void concat (MyString& a, MyString& b);
};
13
задан Tony The Lion 23 July 2010 в 08:47
поделиться

1 ответ

Есть разница между указателем на константу и указателем на константу. Постоянный указатель - это указатель (число - адрес памяти), который нельзя изменить - он всегда указывает на один и тот же объект, заданный при инициализации:

int * const const_pointer = &some_int_var; // will be always pointing to this var
const_pointer = &some_other_var; // illegal - cannot change the pointer
*const_pointer = 2; // legal, the pointer is a pointer to non-const

Указатель на константу - это указатель, указанное значение которого не может быть изменено:

const int * pointer_to_const = &some_int_var; // doesn't have to be always pointing to this var
pointer = &some_other_var; // legal, it's not a constant pointer and we can change it
*pointer = 2; // illegal, pointed value cannot be changed

Вы всегда можете присвоить константу переменной, то есть константный указатель на неконстантный указатель (a). Вы можете преобразовать указатель на неконстантный указатель на константу (b). Но вы не можете преобразовать указатель на const к указателю на неконстантный (c):

int * pointer;
int * const const_pointer = &var;
const int * pointer_to_const;

/* a */
pointer = const_pointer; // OK, no cast (same type)

/* b */
pointer_to_const = pointer; // OK, casting 'int*' to 'const int*'

/* c */
pointer = pointer_to_const; // Illegal, casting 'const int*' to 'int*'

[РЕДАКТИРОВАТЬ] Ниже это не стандартный c ++. Однако это обычное дело. [/ EDIT]
Строковый литерал

"Hello"

преобразуется в постоянный указатель на const ( const char * const ):

char *pointer = "Hello"; // Illegal, cannot cast 'const char*' to 'char*'
char * const const_pointer = "Hello"; // Illegal, cannot cast 'const char*' to 'char*'
const char * pointer_to_const = "Hello"; // OK, we can assign a constant to a variable of the same type (and the type is 'const char*')
"Hello" = pointer_to_const; // Illegal cannot re-assign a constant

В приведенных выше примерах второй - ваш случай. Вы пытались инициализировать указатель на неконстантную с помощью указателя на константу при передаче строкового литерала в качестве аргумента вашей функции. Независимо от того, являются ли эти указатели константами или нет, неважно, на что они указывают.

Краткое описание:
1) Если вы приводите указатель одного типа к указателю другого типа, вы не можете преобразовать указатель на константу в указатель на неконстантный.
2) Если у вас есть постоянный указатель, применяются те же правила, что и к другим константам - вы можете присвоить константу переменной, но вы не можете присвоить переменную константе (кроме ее инициализации).

// ИЗМЕНИТЬ
Как указал GMan, стандарт C ++ 98 (§4.2 / 2) позволяет неявно приводить строковые литералы (которые являются постоянными массивами char) к неконстантному указателю char. Это из-за обратной совместимости (в языке C нет констант).

Конечно, такое преобразование может привести к ошибкам, а компиляторы нарушат правило и покажут ошибку. Однако GCC в режиме совместимости показывает только предупреждение.

22
ответ дан 1 December 2019 в 22:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: