Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Использование const в классах. / 11 сообщений из 11, страница 1 из 1
26.08.2014, 13:41
    #38729009
KA3AKOB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
Вызывает недоумение несколько невнятная разница в конструкциях С++ с модификатором const:

1)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
class B {
typedef unsigned char uchar;
typedef uchar * Puchar;
	void bbb(uchar * ps)		{ps++; *ps=0;}
	void bbb(uchar * const ps)	{      *ps=0;}
//	void bbb(uchar const * ps)	{ps++;       }	
//	void bbb(const uchar * ps)	{ps++;       }	
//	void bbb(Puchar const ps)	{    ; *ps=0;}
//	void bbb(const Puchar ps)	{    ; *ps=0;}
};



Даёт ошибку компиляции:

Код: plaintext
1.
2.
3.
4.
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
b.cpp:
Error E2238 b.cpp 10: Multiple declaration for 'B::bbb(unsigned char *)'
Error E2344 b.cpp 9: Earlier declaration of 'B::bbb(unsigned char *)'
*** 2 errors in Compile ***

То есть компилятор не различает параметр метода uchar * ps и uchar * const ps, хотя я ясно выражаю желание иметь в качестве параметра константный указатель. Точно также реагируют на этот текст cl:

Код: plaintext
1.
2.
3.
4.
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

b.cpp(10) : error C2535: 'void B::bbb(B::uchar *)' : member function already defined or declared
        b.cpp(9) : see declaration of 'B::bbb'


и g++ от Cygwin:

Код: plaintext
1.
b.cpp:10: error: `void B::bbb(unsigned char*)' and `void B::bbb(unsigned char*)' cannot be overloaded

То есть, декларации обоих методов ни одним из этих трёх компиляторов не различаются. Казалось бы...
Однако, если оставить только один второй метод, то он чётко показывает, опять же на всех трёх компиляторах, что const в параметре метода не зря.

При трансляции такого фрагмента ошибок не возникает

Код: plaintext
1.
2.
3.
4.
5.
6.
class B {
typedef unsigned char uchar;
typedef uchar * Puchar;
//	void bbb(uchar * ps)		{ps++; *ps=0;}
	void bbb(uchar * const ps)	{      *ps=0;}
};



Но стоит попытаться изменить сам указатель ps, как тут же выскакивает ошибка компиляции, что совершенно правильно и законно. Понятно, что если работать с первым методом, без const'ов, то всё законно.

Код: plaintext
1.
2.
3.
4.
5.
6.
class B {
typedef unsigned char uchar;
typedef uchar * Puchar;
//	void bbb(uchar * ps)		{ps++; *ps=0;}
	void bbb(uchar * const ps)	{ps++; *ps=0;}
};



Код: plaintext
1.
2.
3.
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
b.cpp:
Error E2024 b.cpp 10: Cannot modify a const object in function B::bbb(unsigned char * const)
*** 1 errors in Compile ***

Что же получается? Компилятор не различает декларации методов, но различает тела? Кстати, если транслировать в ассемблер, то по именам функций видно, что компилятор всё же различает сигнатуры методов. Спрашивается где истина? Различает или не различает?

Далее, пытаемся усовершенствовать декларации с помощью typedef

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
typedef unsigned char uchar;
typedef uchar * Puchar;

class B {
typedef unsigned char uchar;
typedef uchar * Puchar;
	void bbb(Puchar const ps)	{    ; *ps=0;}
	void bbb(const Puchar ps)	{    ; *ps=0;}
};



Код: plaintext
1.
Error E2238 b.cpp 14: Multiple declaration for 'B::bbb(unsigned char * const)'
Error E2344 b.cpp 13: Earlier declaration of 'B::bbb(unsigned char * const)'

Опять не различает. Между тем мне то надо было:

Код: plaintext
1.
2.
	void bbb(uchar * const ps)	{    ; *ps=0;}
	void bbb(const uchar * ps)	{ps++;       }



И вот эти последние две строки чётко различаются компилятором, любым из трёх. Получается, что typedef как-то не совсем так как ожидалось делает определение типа.

Кто объяснит происходящее?
С уважением,
Казаков С.А.
...
Рейтинг: 0 / 0
26.08.2014, 13:51
    #38729022
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
KA3AKOBКто объяснит происходящее?
Выражение любого типа может неявно приводиться к константному. Соответственно различать
константность формальных параметров не имеет смысла: при вызове всё равно будет невозможно
определить какую именно из перегруженных функций надо вызывать.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
26.08.2014, 14:04
    #38729034
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
KA3AKOB,

ты в курсе, что

Код: plaintext
1.
void bbb(uchar * const ps)	{ /*...*/ }



и

Код: plaintext
1.
void bbb(uchar const * ps)	{ /*...*/ }



-- это разные вещи ?

А тут:

Код: plaintext
1.
2.
3.
typedef uchar * Puchar;
	void bbb(Puchar const ps)	{    ; *ps=0;}
	void bbb(const Puchar ps)	{    ; *ps=0;}



ты объявляешь одну и ту же функцию, потому что

Puchar const ps
и
const Puchar ps

-- это одно и тоже :

Код: plaintext
1.
2.
3.
typedef uchar * Puchar;
	void bbb((uchar *) const ps)	{    ; *ps=0;}
	void bbb(const (uchar *) ps)	{    ; *ps=0;}









void bbb(uchar * const ps) { ; *ps=0;}
void bbb(const uchar * ps) {ps++; }
...
Рейтинг: 0 / 0
26.08.2014, 14:38
    #38729090
KA3AKOB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
Уважаемый MasterZiv.
1) В курсе, разные вещи, об этом и пишу. Но я в праве предположить, что конструкция
(Pchar const ps) эквивалентна конструкции (unsigned char * const ps), и соответственно
(const Pchar ps) эквивалентна конструкции (const unsigned char * ps).
Однако, как Вы утверждаете, и я с этим согласен, (unsigned char * const ps) и (const unsigned char * ps) разные вещи.
Почему же, (Pchar const ps) и (const Pchar ps) одинаковы?
По-видимому, так решили разработчики языка и компиляторов, но, по моему мнению, логика слегка шаткая.
2) Конструкции
typedef uchar * Puchar;
void bbb((uchar *) const ps) { ; *ps=0;}
void bbb(const (uchar *) ps) { ; *ps=0;}
не транслируются вовсе и здесь вопросов не возникает.

С уважением,
Казаков С.А.
...
Рейтинг: 0 / 0
26.08.2014, 14:59
    #38729138
KA3AKOB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
Dimitry Sibiryakov,

Благодарю за ответ, но, либо я не совсем Вас понял, либо Вы ошибаетесь во втором утверждении.
Различать константность формальных параметров имеет смысл, поскольку, уже на этапе компиляции можно выявить попытку изменять константный параметр. На этапе трансляции методы, имеющие параметры с модификатором const, это другие функции, нежели те, что имеют параметры без оных модификаторов. Это видно, если транслировать текст С++ в ассемблерный, имена функций будут другие.
Что касается неявного преобразования, то, возможно, так сделали разработчики компилятора, но это странно, повторюсь, потому, что декларации методов не различаются, а реализации различаются компилятором. Поэтому мне и интересно, какие глубокие соображения были у разработчиков языка и компиляторов. Или это недоработка?

С уважением,
Казаков С.А.
...
Рейтинг: 0 / 0
26.08.2014, 15:04
    #38729148
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
KA3AKOBНо я в праве предположить, что конструкция
(Pchar const ps) эквивалентна конструкции (unsigned char * const ps), и соответственно
(const Pchar ps) эквивалентна конструкции (const unsigned char * ps).

неа, не в праве, потому что всё дело в волшебных пузырьках в указателе:

в выражении
Код: plaintext
1.
2.
3.
Pchar const ps; 
// и 
const Pchar ps; 

квалификатор const относится к значению переменной ps типа Pchar, в то время, как
в конструкции
Код: plaintext
1.
unsigned char * const ps 

квалификатор const относится к значению указателя на переменную типа unsigned char,
а в конструкции
Код: plaintext
1.
const unsigned char *ps

квалификатор const относиться к значению типа unsigned char, на которую указывает указатель ps.
конструкция
Код: plaintext
1.
const unsigned char * const ps

является, таким образом, тоже валидной, и показывает, что и указатель, и значение, на которое он указывает - константы, и их менять нельзя.
...
Рейтинг: 0 / 0
26.08.2014, 15:23
    #38729177
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
KA3AKOBэто странно, повторюсь, потому, что декларации методов не различаются, а
реализации различаются компилятором. Поэтому мне и интересно, какие глубокие соображения
были у разработчиков языка и компиляторов. Или это недоработка?
Не зацикливайся на реализации функции. Подумай над её вызовами.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
26.08.2014, 17:15
    #38729333
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
KA3AKOBУважаемый MasterZiv.
1) В курсе, разные вещи, об этом и пишу. Но я в праве предположить, что конструкция
(Pchar const ps) эквивалентна конструкции (unsigned char * const ps), и соответственно
(const Pchar ps) эквивалентна конструкции (const unsigned char * ps).


Ещё раз, давай с нуля разбираться. Ты понимаешь, в чём разница между

Код: plaintext
1.
void bbb(uchar * const ps);


и
Код: plaintext
1.
void bbb(uchar const * ps);



?

Если да, объясни, как ты понимаешь, в чём.

И в чём разница между

Код: plaintext
1.
void bbb(const uchar *  ps);


и
Код: plaintext
1.
void bbb(uchar const * ps);



тоже объясни.
...
Рейтинг: 0 / 0
27.08.2014, 01:55
    #38729662
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
MasterZiv, я понимаю в чём разница :) Можно я объясню :D:D:D
...
Рейтинг: 0 / 0
27.08.2014, 02:42
    #38729667
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
SashaMercury,

В тебе я и не сомневался бы...
Но тут речь о KA3AKOB ...

Ему уже объяснили в принципе, надо только выяснить, понял ли он.
...
Рейтинг: 0 / 0
27.08.2014, 02:59
    #38729671
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование const в классах.
MasterZiv, спасибо что не сомневались C: стараниями Сообщества
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Использование const в классах. / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]