не костантные аттрибуты в константной функции
От: Аноним  
Дата: 19.04.10 12:42
Оценка: :))
Почему в следующем коде, в строчке помеченной //No error!, не возникает ошибки компиляции? Это сишный артефакт?
class Sample
{
    Sample& m_self;
public:
    Sample() : m_self(*this)
    {}

    static void Test(Sample& sample)
    {}

    void Func1() const
    {
        Test(m_self);/////////////////////////////////////////////////////No error!
    }
    void Func2() const
    {
        Test(*this);//error C2664
    }
} sample;
Re: не костантные аттрибуты в константной функции
От: potapov.d  
Дата: 19.04.10 12:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Почему в следующем коде, в строчке помеченной //No error!, не возникает ошибки компиляции? Это сишный артефакт?

А>
А>    void Func1() const
А>    {
А>        Test(m_self);/////////////////////////////////////////////////////No error!
А>    }
А>


3.9.3/3 Each non-static, non-mutable, non-reference data member of a const-qualified class object is const-qualified.

Re: не костантные аттрибуты в константной функции
От: blackhearted Украина  
Дата: 19.04.10 12:51
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Почему в следующем коде, в строчке помеченной //No error!, не возникает ошибки компиляции? Это сишный артефакт?

А>
А>class Sample
А>{
А>    Sample& m_self;
А>public:
А>    Sample() : m_self(*this)
А>    {}

А>    static void Test(Sample& sample)
А>    {}

А>    void Func1() const
А>    {
А>        Test(m_self);/////////////////////////////////////////////////////No error!
А>    }
А>    void Func2() const
А>    {
А>        Test(*this);//error C2664
А>    }
А>} sample;
А>


Ошибка привдения Sample& к const Sample&?

Может я чего-то не понимаю, но при чём тут константность метода?

В Func1 аргументы совпадают.
В Func2 — нет.
Re[2]: не костантные аттрибуты в константной функции
От: vpchelko  
Дата: 19.04.10 13:24
Оценка: :)
Здравствуйте, blackhearted, Вы писали:

B>Здравствуйте, Аноним, Вы писали:


А>>Почему в следующем коде, в строчке помеченной //No error!, не возникает ошибки компиляции? Это сишный артефакт?

А>>
А>>class Sample
А>>{
А>>    Sample& m_self;
А>>public:
А>>    Sample() : m_self(*this)
А>>    {}

А>>    static void Test(Sample& sample)
А>>    {}

А>>    void Func1() const
А>>    {
А>>        Test(m_self);/////////////////////////////////////////////////////No error!
А>>    }
А>>    void Func2() const
А>>    {
А>>        Test(*this);//error C2664
А>>    }
А>>} sample;
А>>


B>Ошибка привдения Sample& к const Sample&?


B>Может я чего-то не понимаю, но при чём тут константность метода?


B>В Func1 аргументы совпадают.

B>В Func2 — нет.
Вообще как бы, можно изменить состояние класса константным методом... Может быть компилятор устарел?
Сало Украине, Героям Сала
Re: не костантные аттрибуты в константной функции
От: andyag  
Дата: 19.04.10 14:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Почему в следующем коде, в строчке помеченной //No error!, не возникает ошибки компиляции? Это сишный артефакт?

А что смущает? Что компилятор не проследил "эквивалентность" *this и m_self?
struct A
{
    void func() { };
};

struct B
{
    A& a;
    B(A& a) : a(a) { }
    void func() const
    {
        a.func();
    }
};

int main()
{
    A a;
    B b(a);
    b.func();
}

Такое тоже смущает?
Re[3]: В С++ за семантику программы отвечает программист, а
От: Erop Россия  
Дата: 19.04.10 14:42
Оценка:
Здравствуйте, vpchelko, Вы писали:

V>Вообще как бы, можно изменить состояние класса константным методом... Может быть компилятор устарел?

IMHO, ты как-то не так понимаешь концепцию константности
Автор: Erop
Дата: 04.09.07
...

Вот тебе пример попроще:
struct IsAllOk {
    IsAllOk() : pReadCount( new int( 0 ) ) {}
    ~IsAllOk() { delete pReadCount;}

    int Read() const { return ++*pReadCount; }

private:
    IsAllOk( const IsAllOk& );
    void operator = ( const sAllOk& );

    int pReadCount;

};
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: В С++ за семантику программы отвечает программист, а
От: saf_e  
Дата: 19.04.10 15:08
Оценка: +1
Здравствуйте, Erop, Вы писали:

E> int pReadCount;

Наверное все-таки:

int *pReadCount;
Re: не костантные аттрибуты в константной функции
От: rg45 СССР  
Дата: 19.04.10 18:42
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Почему в следующем коде, в строчке помеченной //No error!, не возникает ошибки компиляции? Это сишный артефакт?

А>
А>class Sample
А>{
А>    Sample& m_self;
А>public:
А>
А>  Sample() : m_self(*this) { }
А>    
А>  static void Test(Sample& sample) { }
А>
А>  void Func1() const { Test(m_self); } // No error!
А>
А>} sample;
А>




А теперь маленький фокус:

Sample s1;
Sample s2 = s1;


Куда ссылается s2.m_self? Правильно — на s1.

А теперь посмотрим на ситуацию изнутри s2.Func1: член m_self костантного объекта s1 ссылается на неконстантный объект s2. И почему компилятор должен препятствовать вызову Test(m_self)?
--
Re[4]: В С++ за семантику программы отвечает программист, а
От: slava_phirsov Россия  
Дата: 20.04.10 13:16
Оценка:
Здравствуйте, Erop, Вы писали:

E>Вот тебе пример попроще:
struct IsAllOk {
E>    IsAllOk() : pReadCount( new int( 0 ) ) {}
E>    ~IsAllOk() { delete pReadCount;}

E>    int Read() const { return ++*pReadCount; }

E>private:
E>    IsAllOk( const IsAllOk& );
E>    void operator = ( const sAllOk& );

E>    int pReadCount;

E>};


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

return *pReadCount++;


не прокатило бы. ОК все по науке. Остается вопрос, а как в исходном посте компилируется вот это:

Sample() : m_self(*this)


Пробую разжевать, в чем мои непонятки. Если у нас const Sample sample , то this — это const Sample* const, а *this — это, стало быть, const Sample. Так? Как тогда можно инициализировать Sample& m_self через (*this)?

В клиентском коде

const Sample foo;
const Sample& bar = foo;


откомпилируется, а вот

const Sample foo;
Sample& bar = foo;


нет.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[5]: В С++ за семантику программы отвечает программист, а
От: ilvi Россия  
Дата: 21.04.10 05:55
Оценка:
Здравствуйте, slava_phirsov, Вы писали:

_>Остается вопрос, а как в исходном посте компилируется вот это:

_>
_>Sample() : m_self(*this)
_>

В исходном примере именно этой строке ничего не мешает. Наверное, ты неточно выразился.

_>Пробую разжевать, в чем мои непонятки. Если у нас const Sample sample , то this — это const Sample* const, а *this — это, стало быть, const Sample. Так? Как тогда можно инициализировать Sample& m_self через (*this)?


У тебя была инициализация (Sample& sample) через m_self. Если ты все еще про это задаешь вопрос, то смотри:
1) есть this, который у нас Sample const.
2) у это this мы обращаемся к m_self, который у нас (Sample&) const.
Так вот толку от последнего const, нет никакого. (Sample&) const это просто(Sample&).
Re[5]: В С++ за семантику программы отвечает программист, а
От: Erop Россия  
Дата: 21.04.10 07:24
Оценка:
Здравствуйте, slava_phirsov, Вы писали:

_>ОК все по науке. Остается вопрос, а как в исходном посте компилируется вот это:


_>
_>Sample() : m_self(*this)
_>


_>Пробую разжевать, в чем мои непонятки. Если у нас const Sample sample , то this — это const Sample* const, а *this — это, стало быть, const Sample. Так? Как тогда можно инициализировать Sample& m_self через (*this)?


В коде конструктора this не является указателем на константу. Конструктор же нельзя перегрузить по константности создаваемого объекта...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: В С++ за семантику программы отвечает программист, а
От: slava_phirsov Россия  
Дата: 21.04.10 07:46
Оценка:
Здравствуйте, Erop, Вы писали:

E>В коде конструктора this не является указателем на константу. Конструктор же нельзя перегрузить по константности создаваемого объекта...


Кстати, да. Возникает мысль использовать это для какого-нить кулхацкерского финта ушами. Отбрасывание константности без использования mutable полей или const_cast<>
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[6]: В С++ за семантику программы отвечает программист, а
От: slava_phirsov Россия  
Дата: 21.04.10 07:54
Оценка:
Здравствуйте, ilvi, Вы писали:

I>В исходном примере именно этой строке ничего не мешает. Наверное, ты неточно выразился.


Да нет, я точно выразился. В исходном примере не мешает, просто я слегка подумал, и заметил одну штуку... Впрочем, Erop уже все разъяснил.

I>1) есть this, который у нас Sample const.

Именно, что нет! В конструкторе он еще не const, и, apropos, this — это указатель, т.е. Sample* (см. ответ Erop'а на мой пост)

I>2) у это this мы обращаемся к m_self, который у нас (Sample&) const.

Foo& const — не бывает. Только const Foo& (в отличие от указателей, где может быть const Foo *, Foo const *, Foo * const и даже const Foo * const)
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[7]: В С++ за семантику программы отвечает программист, а
От: rg45 СССР  
Дата: 21.04.10 08:08
Оценка:
Здравствуйте, slava_phirsov, Вы писали:

_>Здравствуйте, Erop, Вы писали:


E>>В коде конструктора this не является указателем на константу. Конструктор же нельзя перегрузить по константности создаваемого объекта...


_>Кстати, да. Возникает мысль использовать это для какого-нить кулхацкерского финта ушами. Отбрасывание константности без использования mutable полей или const_cast<>


mutable и const_cast — средства для снятия константности с уже существующего объекта. А конструктор, даже если это конструктор копии, создает новый объект, и снять константность уже с существующего объекта с его помощью нельзя.

А невозможность специфицировать коструктор как константный или неконстантный — это не упущение и не финт и не что-то еще. Семантика конструктора такова, что пока объект не создан (а время жизни объекта согласно стандарту и здравому смыслу начинается ПОСЛЕ выхода из его конструктора), говорить о его константности или неконстантности бессмысленно.
--
Re[8]: В С++ за семантику программы отвечает программист, а
От: slava_phirsov Россия  
Дата: 21.04.10 08:11
Оценка:
Здравствуйте, rg45, Вы писали:

R>mutable и const_cast — средства для снятия константности с уже существующего объекта. А конструктор, даже если это конструктор копии, создает новый объект, и снять константность уже с существующего объекта с его помощью нельзя.


Это я понимаю, я немного другое имею в виду.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[7]: В С++ за семантику программы отвечает программист, а
От: Erop Россия  
Дата: 21.04.10 08:28
Оценка:
Здравствуйте, slava_phirsov, Вы писали:

_>Кстати, да. Возникает мысль использовать это для какого-нить кулхацкерского финта ушами. Отбрасывание константности без использования mutable полей или const_cast<>


Если константность истинная, то велика вероятность нарваться на UB...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: В С++ за семантику программы отвечает программист, а
От: slava_phirsov Россия  
Дата: 21.04.10 08:46
Оценка:
Здравствуйте, rg45, Вы писали:

R>mutable и const_cast — средства для снятия константности с уже существующего объекта. А конструктор, даже если это конструктор копии, создает новый объект, и снять константность уже с существующего объекта с его помощью нельзя.


Вот пример, как можно сделать эрзац-mutable

#include <iostream>
using namespace std;

class Foo
{
 Foo& _self;
 int _n; // Можно было объявить как mutable и не париться, но мы комсомольцы, мы учимся трудности преодолевать

public:
 Foo(): _self(*this), _n(0) {};
 int bar() const {return _self._n++;}
};

int main()
{
 {
  Foo foo;
  cout << foo.bar() << endl;
  cout << foo.bar() << endl;
  cout << foo.bar() << endl;
  }
{
  const Foo foo;
  cout << foo.bar() << endl;
  cout << foo.bar() << endl;
  cout << foo.bar() << endl;
  }
}
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[8]: В С++ за семантику программы отвечает программист, а
От: uzhas Ниоткуда  
Дата: 21.04.10 08:47
Оценка:
Здравствуйте, rg45, Вы писали:

R>А невозможность специфицировать коструктор как константный или неконстантный — это не упущение и не финт и не что-то еще. Семантика конструктора такова, что пока объект не создан (а время жизни объекта согласно стандарту и здравому смыслу начинается ПОСЛЕ выхода из его конструктора), говорить о его константности или неконстантности бессмысленно.


Мое личное мнение — константность методов и объектов — это плод больного воображения. Имеем необоснованное усложнение языка. Существуют ли другие языки программирования с подобной "фичей"?
Re[8]: В С++ за семантику программы отвечает программист, а
От: Erop Россия  
Дата: 21.04.10 09:27
Оценка:
Здравствуйте, rg45, Вы писали:

R>А невозможность специфицировать коструктор как константный или неконстантный — это не упущение и не финт и не что-то еще. Семантика конструктора такова, что пока объект не создан (а время жизни объекта согласно стандарту и здравому смыслу начинается ПОСЛЕ выхода из его конструктора), говорить о его константности или неконстантности бессмысленно.


Почему это бессмысленно? Почему мне нельзя узнать внутри конструктора, константу я строю или нет?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: Не хочешь -- не ешь...
От: Erop Россия  
Дата: 21.04.10 09:29
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Мое личное мнение — константность методов и объектов — это плод больного воображения. Имеем необоснованное усложнение языка. Существуют ли другие языки программирования с подобной "фичей"?


Ну так не используй... Это же сервис, предоставляемый языком программисту.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.