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;
}
num = src.num;
den = src.den;
}
то все работает хорошо. Но вот если такой:
Код:
fraction(fraction const &src){
num = src.[COLOR="#0000ff"]get_num();[/COLOR]
den = src.[COLOR="#0000ff"]get_den()[/COLOR];
}
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();
}
num = src.get_num();
den = src.get_den();
}
Не могу сам разобраться=( Помогите=)
int get_num() const {
return num;
}
int get_den() const {
return den;
}
Я кажется немного разобрался.
Если после функции стоит ключевое слово const это значит что эту функцию можно вазывать из других const функций и самое главное что разрешается вызывать из функций, где запрещено изменять обьект данного класса, то есть которые имеют аргумент const fraction.
Листаю стандарт(Точнее Герберта Шилдта), не могу найти подробное пояснение на эту тему: в квалификаторах const и volitile про это не сказано. В каком же это разделе....?
Язык программирования C++. Лекции и упражнения
5-е издание
Стивен Прата
В книге Брюса Эккеля "Философия С++ Том 1. Введение в стандартный С++" содержится всестороннее обсуждение понятия константности и его реализации в языке. Очень советую (и главу 8 и книгу в целом). Электронный вариант можно скачать с c-books.info
Я кажется немного разобрался.
Если после функции стоит ключевое слово const это значит что эту функцию можно вазывать из других const функций и самое главное что разрешается вызывать из функций, где запрещено изменять обьект данного класса, то есть которые имеют аргумент const fraction.
Листаю стандарт(Точнее Герберта Шилдта), не могу найти подробное пояснение на эту тему: в квалификаторах const и volitile про это не сказано. В каком же это разделе....?[/QUOTE]
Не совсем.
Константный обджект может использовать только константные методы.
Вот-так верней будет.
Константный метод может вызывать неконстантные методы и изменять поля класса. Для этого нужно вписать внутрь него определённые директивы предпроцессора (#pragma option push ....)
[QUOTE=el scorpio]Константный метод может вызывать неконстантные методы и изменять поля класса. Для этого нужно вписать внутрь него определённые директивы предпроцессора (#pragma option push ....)[/QUOTE]Какие нафиг директивы? Все обходится через const_cast. Вообще говоря, можно обойти все что угодно, вплоть до вызова приватного метода.
const_cast (равно как и другие переопределения) указателя this - дурной тон, к которому следует прибегать только когда компилятор иначе поступать не позволяет.
Просто, если изменять объект в константных методах, при компиляции будет много warning'ов - их выдача и глушится директивами. Соответственно, в конце функции нужно будет написать "#pragma option pop" для восстановления параметров компиляции.
const_cast (равно как и другие переопределения) указателя this - дурной тон, к которому следует прибегать только когда компилятор иначе поступать не позволяет.
Просто, если изменять объект в константных методах, при компиляции будет много warning'ов - их выдача и глушится директивами. Соответственно, в конце функции нужно будет написать "#pragma option pop" для восстановления параметров компиляции.[/QUOTE]Я считаю, что менять объект в константном методе - дурной тон и использование const_cast и mutable не приветствую. Но если использовать const_cast, то ни каких ворнингов не будет, так-что непонимаю вообще зачем директивы нужны в данном случае? А без const_cast компилятор должен выдать ошибку.
const_cast (равно как и другие переопределения) указателя this - дурной тон, к которому следует прибегать только когда компилятор иначе поступать не позволяет.
[/QUOTE]
Иш как....
Прошу прощения за неточность.
В константых методах нельзя изменять поля класса. Можно только менять свойства переопределённого this.
Зато вызывать неконстантые методы вполне можно, но это будет warning - для его глушения и используются директивы
Так что вместо изменения поля лучше вызывать встроенный неконстантый метод.
Код:
TRes TMyClass::ConstFunc (TParams Params) const
{
#pragma option push -w-ncf
//....
this->SetParams (Params); // вызов неконст. метода
//....
#pragma option push -w-ncf
}
{
#pragma option push -w-ncf
//....
this->SetParams (Params); // вызов неконст. метода
//....
#pragma option push -w-ncf
}
el scorpio - видиш дверь??? Вон иди, иди, иди.... пока не попадеш туда, где обсуждается работа с твоим компилятором, и не *би моск. Здесь люди на Visual C++ пишут.
А вот хамить не надо :mad: - особенно по телефону и сети - выглядит просто глупо.
И не надо мне говорить, будто MSVC не использует директивы :eek:
А вот хамить не надо :mad: - особенно по телефону и сети - выглядит просто глупо.
И не надо мне говорить, будто MSVC не использует директивы :eek:[/QUOTE]Согласен с Alexandoros. Перед тем как постить, проверь на MSVC. Конечно, он поддерживает директивы, но свои и вызвать неконстантный метод из константного НЕЛЬЗЯ!!!
P.S. за kнижки thnk)))