Dashia18 / Simple_fraction_class

Class of simple fraction
0 stars 0 forks source link

Передача объектов методам #2

Closed sergregory closed 9 years ago

sergregory commented 9 years ago
void Simple_fraction::print_simple_fraction(std::string sf_name)
...

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

void Simple_fraction::print_simple_fraction(const std::string& sf_name)
...
Dashia18 commented 9 years ago

Сделала передачу параметров по константной ссылке в нескольких местах.

1) Объявление: void add_sf(const Simple_fraction& sf_b); Вызов: sf_a.add_sf(sf_b); //Здесь понятно, передается параметр в виде переменной. мы передаем ее адрес и делаем константный, что бы его нельзя было изменить. Правда если ссылка простая то работает, а если константная ошибка: int d2 = sf_b.get_denominatior(); Ошибка 2 error C2662: Simple_fraction::get_denominatior: невозможно преобразовать указатель "this" из "const Simple_fraction" в "Simple_fraction &" d:\programming\simple_fraction_class\simple_fraction.cpp 127 1 Simple_fraction_project_VS

2)Объявление: void set_simple_fraction(int num, int den); Вызов: sf_a.set_simple_fraction(3,4); //Мы не делаем его ссылкой так как он у нас изменяется но в принципе это можно сделать? Как он узнает его адрес если это не переменная, а параметра, тоже для 3)?

3)Объявление: void print_simple_fraction(const std::string& sf_name); Вызов: sf_a.print_simple_fraction("sf_a");

//Почему он ругается на неконстантность. что-то я не поняла все таки почему она не может быть неконстантной. Ошибка 9 error C2664: Simple_fraction::print_simple_fraction: невозможно преобразовать параметр 1 из "const char [5]" в "std::string &" d:\programming\simple_fraction_class\main.cpp 11 1 Simple_fraction_project_VS

sergregory commented 9 years ago

Давай начнём с третьего было:

 void print_simple_fraction(const std::string& sf_name);

стало

 void print_simple_fraction(std::string& sf_name);

И вызов:

sf_a.print_simple_fraction("sf_a");

Строка "cf_a" это константа, и имеет тип const char [5] И тут получается проблема - мы хотим из константной строки сделать неконстантную. Компилятор ругается.

sergregory commented 9 years ago

Про 2) в случае "примитивных" типов (встроенные типы int, char, long, double и так далее) нет смысла (с точки зрения эффективности) передавать параметр по ссылке - ссылка и переменная займут в памяти примерно одинаковое количество места. Однако, если ты планируешь изменить значение параметра внутри функции так, чтобы новое значение было доступно снаружи вункции (то есть вернуть результат выполнения функции через параметр) то передача по ссылке - то что нужно

sergregory commented 9 years ago

Про 2) и 3) - для так случаев, когда мы передаём так называемый "литерал" - число или строчку в кавычках - компилятор создаёт временный объект, инициализирует нужным значением и берёт его адрес То есть строка

sf_a.print_simple_fraction("sf_a");

Превращается во что-то типа

const char tmp[5] = "sf_a";
sf_a.print_simple_fraction(tmp);
sergregory commented 9 years ago

Про 1) Проблема в том, что у всех методов класса есть неявный первый аргумент - указатель на объект класса. То есть для компилятора описание метода get_denominatior выглядит так:

int get_denominator(Simple_fraction* );

И поэтому возникает ошибка - мы пытаемся у константного объекта (мы же параметр передали как константную ссылку) вызвать метод, который хочет работать с ним как с не константным. Чтобы ошибки не было, нужно компилятору сказать, что метод get_denominator не меняет объект, для которого его вызывают, и, значит, его можно использовать с константными объектами. Для этого у метода есть спецификатор const

class Simple_fraction{
public:
...
int get_denominator() const;
...
}

Тогда компилятор будет видеть этот метод как

int get_denominator(const Simple_fraction* );

и сможет вызывать его и для константных и для неконстантных объектов

sergregory commented 9 years ago

:+1: