Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Почему конструктор копирования не может воспользоваться открытой функцией-членом свое

7.0K
29 октября 2006 года
pink master
79 / / 21.10.2006
Почему конструктор копирования не может воспользоваться открытой функцией-членом своего класса, если экземпляр передаётся по ссылке и не должен быть изменен(const)?
Есть простенький класс:
Код:
class fraction{
private:
    int num,den;
public:
    ....конструкторы....
   
    void set(int new_num, int new_den){
    num = new_num;
    den = new_den;
     }

    int get_num(){
        return num;
    }

    int get_den(){
        return den;
    }
};


Если добавить в него такой конструктор копирования:
 
Код:
fraction(fraction const &src){
    num = src.num;
    den = src.den;
}

то все работает хорошо. Но вот если такой:
 
Код:
fraction(fraction const &src){
    num = src.[COLOR="#0000ff"]get_num();[/COLOR]
    den = src.[COLOR="#0000ff"]get_den()[/COLOR];
}


то вылезает ошибка:

D:\coding\c++\Ffloat\fraction_class.h(105) : error C2662: 'get_num' : cannot convert 'this' pointer from 'const class fraction' to 'class fraction &'
Conversion loses qualifiers
D:\coding\c++\Ffloat\fraction_class.h(106) : error C2662: 'get_den' : cannot convert 'this' pointer from 'const class fraction' to 'class fraction &'
Conversion loses qualifiers

Почему так нельзя? Ведь потомок такого класса уже не имеет прямого доступа к закрытым членам, и приходиться писать такой конструктор копирования(без const):
 
Код:
New_fraction([COLOR="#0000ff"]fraction &src[/COLOR]){
    num = src.get_num();
    den = src.get_den();
}


Не могу сам разобраться=( Помогите=)
5.4K
29 октября 2006 года
Svyatozar
221 / / 11.09.2006
При объявлении функций которые не меняют содержимое объекта добавляй const:


int get_num() const {
return num;
}

int get_den() const {
return den;
}
7.0K
29 октября 2006 года
pink master
79 / / 21.10.2006
точно, спасибо=) абсолютно верно:
Я кажется немного разобрался.
Если после функции стоит ключевое слово const это значит что эту функцию можно вазывать из других const функций и самое главное что разрешается вызывать из функций, где запрещено изменять обьект данного класса, то есть которые имеют аргумент const fraction.
Листаю стандарт(Точнее Герберта Шилдта), не могу найти подробное пояснение на эту тему: в квалификаторах const и volitile про это не сказано. В каком же это разделе....?
5.4K
29 октября 2006 года
Svyatozar
221 / / 11.09.2006
купи хорошую книгу, не пожалеешь потраченных копеек. Начинающим рекомендую достать

Язык программирования C++. Лекции и упражнения
5-е издание
Стивен Прата
23K
29 октября 2006 года
Ulysses
1 / / 29.10.2006
В книге Брюса Эккеля "Философия С++ Том 1. Введение в стандартный С++" содержится всестороннее обсуждение понятия константности и его реализации в языке. Очень советую (и главу 8 и книгу в целом). Электронный вариант можно скачать с c-books.info
398
30 октября 2006 года
Alexandoros
630 / / 21.10.2005
[QUOTE=pink master]точно, спасибо=) абсолютно верно:
Я кажется немного разобрался.
Если после функции стоит ключевое слово const это значит что эту функцию можно вазывать из других const функций и самое главное что разрешается вызывать из функций, где запрещено изменять обьект данного класса, то есть которые имеют аргумент const fraction.
Листаю стандарт(Точнее Герберта Шилдта), не могу найти подробное пояснение на эту тему: в квалификаторах const и volitile про это не сказано. В каком же это разделе....?[/QUOTE]
Не совсем.

Константный обджект может использовать только константные методы.
Вот-так верней будет.
309
30 октября 2006 года
el scorpio
1.1K / / 19.09.2006
Константный метод может вызывать неконстантные методы и изменять поля класса. Для этого нужно вписать внутрь него определённые директивы предпроцессора (#pragma option push ....)
395
30 октября 2006 года
RelB
367 / / 09.11.2002
[QUOTE=el scorpio]Константный метод может вызывать неконстантные методы и изменять поля класса. Для этого нужно вписать внутрь него определённые директивы предпроцессора (#pragma option push ....)[/QUOTE]Какие нафиг директивы? Все обходится через const_cast. Вообще говоря, можно обойти все что угодно, вплоть до вызова приватного метода.
309
30 октября 2006 года
el scorpio
1.1K / / 19.09.2006
RelB
const_cast (равно как и другие переопределения) указателя this - дурной тон, к которому следует прибегать только когда компилятор иначе поступать не позволяет.
Просто, если изменять объект в константных методах, при компиляции будет много warning'ов - их выдача и глушится директивами. Соответственно, в конце функции нужно будет написать "#pragma option pop" для восстановления параметров компиляции.
395
30 октября 2006 года
RelB
367 / / 09.11.2002
[QUOTE=el scorpio]RelB
const_cast (равно как и другие переопределения) указателя this - дурной тон, к которому следует прибегать только когда компилятор иначе поступать не позволяет.
Просто, если изменять объект в константных методах, при компиляции будет много warning'ов - их выдача и глушится директивами. Соответственно, в конце функции нужно будет написать "#pragma option pop" для восстановления параметров компиляции.[/QUOTE]Я считаю, что менять объект в константном методе - дурной тон и использование const_cast и mutable не приветствую. Но если использовать const_cast, то ни каких ворнингов не будет, так-что непонимаю вообще зачем директивы нужны в данном случае? А без const_cast компилятор должен выдать ошибку.
398
30 октября 2006 года
Alexandoros
630 / / 21.10.2005
[QUOTE=el scorpio]RelB
const_cast (равно как и другие переопределения) указателя this - дурной тон, к которому следует прибегать только когда компилятор иначе поступать не позволяет.
[/QUOTE]

Иш как....
309
30 октября 2006 года
el scorpio
1.1K / / 19.09.2006
RelB и все, все, все...
Прошу прощения за неточность.
В константых методах нельзя изменять поля класса. Можно только менять свойства переопределённого this.

Зато вызывать неконстантые методы вполне можно, но это будет warning - для его глушения и используются директивы
Так что вместо изменения поля лучше вызывать встроенный неконстантый метод.

 
Код:
TRes TMyClass::ConstFunc (TParams Params) const
{
#pragma option push -w-ncf
//....
   this->SetParams (Params); // вызов неконст. метода
//....
#pragma option push -w-ncf
}
398
30 октября 2006 года
Alexandoros
630 / / 21.10.2005
el scorpio - видиш дверь??? Вон иди, иди, иди.... пока не попадеш туда, где обсуждается работа с твоим компилятором, и не *би моск. Здесь люди на Visual C++ пишут.
309
31 октября 2006 года
el scorpio
1.1K / / 19.09.2006
Alexandroros
А вот хамить не надо :mad: - особенно по телефону и сети - выглядит просто глупо.

И не надо мне говорить, будто MSVC не использует директивы :eek:
395
31 октября 2006 года
RelB
367 / / 09.11.2002
[QUOTE=el scorpio]Alexandroros
А вот хамить не надо :mad: - особенно по телефону и сети - выглядит просто глупо.

И не надо мне говорить, будто MSVC не использует директивы :eek:[/QUOTE]Согласен с Alexandoros. Перед тем как постить, проверь на MSVC. Конечно, он поддерживает директивы, но свои и вызвать неконстантный метод из константного НЕЛЬЗЯ!!!
7.0K
31 октября 2006 года
pink master
79 / / 21.10.2006
да уж.....столько эмоций из-за компилятора......
P.S. за kнижки thnk)))
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог