Conversation
| std::cout << color_ << " car has been created\n"; | ||
| } | ||
| Car::~Car() | ||
| { std::cout << color_ << " car has been destroied\n"; } |
There was a problem hiding this comment.
мелочь. но старайся сразу писать код в одном стиле (см. размещение фигурных скобок здесь и выше)
Lesson_9/SmartPointer/Driver.h
Outdated
| Driver(const std::string& name, std::shared_ptr<CarFactory> factory); | ||
| void BuyCar(const std::string& color); | ||
| void BuyUsedCar(Driver* d); | ||
| std::unique_ptr<Car> CellCar(); |
There was a problem hiding this comment.
спасибо. исправил. хорошо что не видела моя учительница по английскому ;-)
Lesson_9/SmartPointer/Driver.h
Outdated
| @@ -0,0 +1,20 @@ | |||
| #pragma once | |||
| #include "stdafx.h" | |||
There was a problem hiding this comment.
этот здесь не нужен - перенеси в cpp
Lesson_9/SmartPointer/stdafx.h
Outdated
| #include <iostream> | ||
| #include <string> | ||
| #include <memory> | ||
| #include "Driver.h" |
There was a problem hiding this comment.
свои файлы лучше по месту подключать
Lesson_9/SmartPointer/Car.h
Outdated
| @@ -0,0 +1,12 @@ | |||
| #pragma once | |||
| #include "stdafx.h" | |||
Lesson_9/SmartPointer/CarFactory.h
Outdated
| @@ -0,0 +1,9 @@ | |||
| #pragma once | |||
| #include "stdafx.h" | |||
Lesson_9/SmartPointer/Driver.h
Outdated
| Driver(const std::string& name, std::shared_ptr<CarFactory> factory); | ||
| void BuyCar(const std::string& color); | ||
| void BuyUsedCar(Driver* d); | ||
| std::unique_ptr<Car> CellCar(); |
There was a problem hiding this comment.
спасибо. исправил. хорошо что не видела моя учительница по английскому ;-)
Lesson_9/SmartPointer/autoschool.cpp
Outdated
| //std::unique_ptr < Driver> currentDriver(new Driver("Ivan", factory_)); | ||
| //DriversInAutoschool_.push_back(std::move(currentDriver)); | ||
| //secondway: same but less code | ||
| DriversInAutoschool_.push_back(std::unique_ptr < Driver>(new Driver("Ivan", factory_))); |
There was a problem hiding this comment.
странно, до разьединения на файлы классов работала вставка драйверов и менеджеров в класс, почему сейчас не работает?! это дело в том что я опять неверно подключил в файлах другие файлы?!
There was a problem hiding this comment.
в autoschool.h не видны CarFactory, Driver и DriverManager
| { | ||
| std::cout << "go! ";//it works! | ||
| //failed to implement through functor and this line stil doesn't work: | ||
| std::thread th_(&ThreaFunctionManager,OneDriver_); |
There was a problem hiding this comment.
в этой строке у меня ошибка. подскажи как решить - не собирается даже, чтобы отдебажить (((
реализация через перегрузку оператора крутые скобки тоже не далась мне...
There was a problem hiding this comment.
такой вариант тоже не собирается: std::thread th_(&DriverManager::ThreaFunctionManager,&OneDriver_);
Lesson_9/SmartPointer/autoschool.cpp
Outdated
| DriverManagers_[i].GetOneDriver(std::move(std::unique_ptr<Driver>(DriversInAutoschool_[j].release()))); | ||
| j++; | ||
| DriverManagers_[i].setFiledManagerToOnedDrivers(0); | ||
| DriverManagers_[i].GetOneDriver(std::move(std::unique_ptr<Driver>(DriversInAutoschool_[j].release()))); |
There was a problem hiding this comment.
этот участок точно не дебажил :(
после первого вызова release() в unique_ptr будет nullptr.
There was a problem hiding this comment.
будет и ок. дальше j++ и мы передаём драйверов дальше. именно этот участок дебажил вчера. вроде ничего не менял критично
There was a problem hiding this comment.
если я не увидел проблемы - прошу укажи мне на неё. сейчас повторю дэбаг этого участка.
тут логика такая что раз я решил, что у менеджера только два водителя - упрощение на этапе создания программы - то вот такой механизм их записи сделал, когда счётчик идёт по номеру менеджера, а драйверов в два раза больше по числу.
Lesson_9/SmartPointer/Driver.cpp
Outdated
| if (!this->HaveCar()) | ||
| { | ||
| std::vector<int > temp = this->canIbuyUsedCar(); | ||
| int y = temp.empty(); |
There was a problem hiding this comment.
надо было закоментировать мои строки "для отладки". сори. это только для отладки
Lesson_9/SmartPointer/Driver.cpp
Outdated
| bool probaPera = this->HaveCar(); | ||
| if (!this->HaveCar()) | ||
| { | ||
| std::vector<int > temp = this->canIbuyUsedCar(); |
There was a problem hiding this comment.
судя по имени функции canIBuyUsedCar() она должна возвращать true/false, но ни как ни вектор
There was a problem hiding this comment.
да название отстало от реализации. надо переименовать во что-то типа canIBuyUsedCarIFCanGIVEManagerAndDriver()
Lesson_9/SmartPointer/Driver.cpp
Outdated
| mtx.lock(); | ||
| //std::lock_guard<std::mutex>lock(mtx); | ||
| this->Go(); | ||
| bool probaPera = this->HaveCar(); |
There was a problem hiding this comment.
именование переменных забавное, но и тебя сбивает и в ревью не понятно
There was a problem hiding this comment.
это для дебага - понимать состояние - ещё раз прости. на будущее закоментирую вовсе или оставлю комментарий что это для дебага.
Lesson_9/SmartPointer/Driver.cpp
Outdated
| int i = 100; | ||
| while (i) | ||
| { | ||
| mtx.lock(); |
There was a problem hiding this comment.
для того, чтобы покупка и поиск для покупки usedCar прошёл без вмешаетльства других потоков
Lesson_9/SmartPointer/Driver.cpp
Outdated
| { | ||
| currentSchool; // ������� ��� ������ �������� � ������� | ||
| return 1; | ||
| std::vector <int> temp = myManager_->isDriverToBuyCarFromAllManagers_m(mySchool_); |
There was a problem hiding this comment.
isDriverToBuyCarFromAllManagers_m - судя по названию должна true или false возвращать
There was a problem hiding this comment.
возможна и такая логика, но у меня возвращает дополнительно 1 или 2 - и так сразу решает две задачи, чтобы меньше вызовов было, по сути одинаковых.
There was a problem hiding this comment.
можешь объяснить, что такое 1, что такое 2 ?
There was a problem hiding this comment.
в векторе DriversOwnedByManagers_ у меня жётско зашито - только два драйвера.
1 - значит есть авто у DriversOwnedByManagers_[0] - то есть первого драйвера у этого мэнеджера
1 - значит есть авто у DriversOwnedByManagers_[2] - то есть второго драйвера у этого мэнеджера
если 0 - значит у этого мэнеджера нет драйверов с авто
Lesson_9/SmartPointer/Driver.cpp
Outdated
| { | ||
| std::vector<int > temp = this->canIbuyUsedCar(); | ||
| int y = temp.empty(); | ||
| if (temp.empty())//If temp.empty==1 than meens temp is empty |
There was a problem hiding this comment.
empty() возвращает true/false https://en.cppreference.com/w/cpp/container/vector/empty
There was a problem hiding this comment.
знаю это и что?!
There was a problem hiding this comment.
выше приравниваешь к инту, здесь коммент
//If temp.empty==1
There was a problem hiding this comment.
если ты к тому что так (temp.empty()==1) более понятно, то согласен. Буду применять. Если иначе - прошу дать комментарий
There was a problem hiding this comment.
я к тому, что "выше приравниваешь к инту, а здесь коммент //If temp.empty==1"
не нужно bool с интом стравнивать.
т.е. в условии if((temp.empty()) правильная запись
Lesson_9/SmartPointer/Driver.cpp
Outdated
| std::cout << std::endl << "Get Ready!" << std::endl; | ||
| //this->BuyUsedCar(); | ||
| //line below doesn't work | ||
| //car_ = mySchool_->giveUsedCarFromDriversOwnedManagers(temp);//you should work with metods not fields |
There was a problem hiding this comment.
а можешь тут рассказать какая была идея. что за temp? какая дальше логика в giveUsedCarFromDriversOwnedManagers?
There was a problem hiding this comment.
в giveUsedCarFromDriversOwnedManagers() передаётся вектор.
Выше мы смотрим, если он пустой, то в else не заходим. Если не пстой - то в нём записано два числа - первое число это номер мэнеджера в векторе мэнедежров-мэмбер автошколы-DriverManagers_ и второе число - это номер драйвера в векторе DriversOwnedByManagers_ то есть это номер драйвера в векторе - которым владеет только один мэнеджер.
Возвращаемся к giveUsedCarFromDriversOwnedManagers(). Вызывает её водитель, обращаясь к автошколе - своему родителю, передавая ей в виде вектора CoordinatesOfDriverHasCar два числа: номер менеджера и номер драйвера у этого менеджера. Функция giveUsedCarFromDriversOwnedManagers() сама обращается к этому драйверу сразу в return DriverManagers_[CoordinatesOfDriverHasCar[0]] где просит его выполнить метод tellDriverTosellCar, передавая в него номер водителя- он записан во втором элементе вектора CoordinatesOfDriverHasCar[1]. По сути это запрос внутри мэмбера мэнеджера продать машину. При переходу к этому методу видим DriversOwnedByManagers_[index]->SellCar();
И именно вот этот сквозной возврат уникального указателя у меня "не срабатывает". Я понятно изложил заложенную механику?
PS При покупке бу авто я отошёл от логики использования функции BuyUsedCar, потому что драйвер
There was a problem hiding this comment.
вообще стало не на много понятнее :)
вектор возвращается из this->canIbuyUsedCar() ? что в ней происходит?
| #include "Car.h" | ||
| #include "autoschool.h" | ||
|
|
||
| int DriverManager::NumberOfManagers = 0; |
There was a problem hiding this comment.
ага, была попытка статический член использовать, но он не потребовался. С этого улыбаешься или что-то ещё?
There was a problem hiding this comment.
статические переменные это уже как мемчик )
| //OneDriver_->Go(); | ||
| } | ||
| void DriverManager::ThreaFunctionManager() | ||
| void DriverManager::ThreaFunctionManager()//previous version |
There was a problem hiding this comment.
у тебя же есть отличный инструмент контроля версий.
подобные комментарии //previous version - тебя же самого запутывают
There was a problem hiding this comment.
да, это так. просто сюда я заливаю готовые решение, а где хранить промежуточные - в ходе создания программы и отладки. чтобы быстро "откатиться" назад, оставляю код и комментрию его. Подскажи как делать иначе?! пушить в "свой" репозхиторий?! а потом научиться "из него откатываться" до "предыдущей стабильной версии"?
There was a problem hiding this comment.
сюда нужно заливать все промежуточные. почему нет?
| std::vector <int> DriverManager::isDriverToBuyCarFromAllManagers_m(autoschool* currentSchool) | ||
| { | ||
| std::vector <int> temp = currentSchool->isDriverToBuy_as(); | ||
| bool r=temp.empty(); |
There was a problem hiding this comment.
выше уже отписался. вектор тут возвращается. буду иначе именовать функции или разделять на две - одна будет возвращать bool а вторая отрабаывать и возвращать номер,если true
| } | ||
| std::vector <int> DriverManager::isDriverToBuyCarFromAllManagers_m(autoschool* currentSchool) | ||
| { | ||
| std::vector <int> temp = currentSchool->isDriverToBuy_as(); |
There was a problem hiding this comment.
что означают суффиксы _m _as в именовании функций?
There was a problem hiding this comment.
m - функция мэнеджера, а as - функция автошколы
| { | ||
| //OneDriver_->Go(); | ||
| DriversOwnedByManagers_[0]->cleverGo(); | ||
| DriversOwnedByManagers_[1]->cleverGo(); |
There was a problem hiding this comment.
почему-то стартует строка 31 в потоке, а строка 32 - нет ((( и того вместо того, чтобы обработать два объекта в одном потоке - и у обоих запустить cleverGo, я запускаю только одного - который вызван в строке 31.
Сам посмотрю ещё. Интересно твоё мнение профессионала - где здесь и что я упустил из виду. Пока не смог найти сам.
|
|
||
| std::unique_ptr<Car> CarFactory::BuildCar(const std::string& color) | ||
| { | ||
| return std::unique_ptr<Car>(new Car(color)); |
Lesson_9/SmartPointer/Driver.cpp
Outdated
| std::mt19937 gen(rd()); | ||
| std::uniform_int_distribution<> distrib(1, 2); | ||
| int random_number = distrib(gen); | ||
| std::lock_guard<std::mutex> locked(mtx); |
There was a problem hiding this comment.
все драйверы будут выполнять Drive() и операции с покупкой/продажей последовательно, что не ок
нужно сузить область синхронизации до минимально необходимой
Lesson_9/SmartPointer/Driver.cpp
Outdated
| } | ||
| } | ||
| } | ||
| void Driver::Go()//already dont use in prog |
There was a problem hiding this comment.
если не используется не нужно оставлять
| int intRand(const int& min, const int& max); | ||
| private: | ||
| std::unique_ptr<Car> car_; | ||
| std::shared_ptr<CarFactory> factory_; |
There was a problem hiding this comment.
почему factory в shared, а manager и school в обычном указателе?
There was a problem hiding this comment.
потому что они никуда и никому не передаются. в данном контексте, по аналогии с factory - можно было использовать shared_ptr для manager и school. Для практики
There was a problem hiding this comment.
я тебя понял. тогда очевидно программа ляжет, так как случится UB. урок данного урока в том что если использовать указатели, то только умные в дальнейшем: shared или unique.
| { | ||
|
|
||
| int i = 4; | ||
| while (i) |
There was a problem hiding this comment.
for в таком случае выглядит очевиднее
There was a problem hiding this comment.
на будущее принято
| std::vector<std::thread> threads; | ||
| for (unsigned currentDriverNumber = 0; currentDriverNumber < DriversOwnedByManagers_.size(); ++currentDriverNumber) | ||
| { | ||
| std::random_device rd; |
There was a problem hiding this comment.
генерация случайного числа дублируется - можно в отдельную функцию вынести
There was a problem hiding this comment.
ты имеешь ввиду вынести в отдельную функцию вот эти три строки, под первой из которых ты и оставил этот комментарий?!
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distrib(1, 2);
There was a problem hiding this comment.
понял. этот код в двух местах, но в этом он не нужен - перенёс его уже полностью в cleverGo();
There was a problem hiding this comment.
точнее он там и был. оставил только там
| { | ||
| throw std::runtime_error ("...tried to buy a used car but they aren�t\n"); | ||
| } | ||
| Driver* p_DriverWithCar = PtrDriversWithCar_.back(); |
There was a problem hiding this comment.
что если в элементе контейнера окажется nullptr
There was a problem hiding this comment.
плохо будет, но вроде как логикой программы это непредусмотренно. В какой ситуации это возможно?!
Как я понимаю ты предлагаешь тут поставить некую проверку, на всякий случай? Например на случай, если вдруг другой программист поменяет логику функции, которая записывает данные в данный вектор.
| } | ||
| Driver* DriverManager::GivePtrDriverWithCar() | ||
| { | ||
| if (PtrDriversWithCar_.empty()) |
There was a problem hiding this comment.
обращение к контейнеру синхронизированно между потоками? не получится, что один записывает/удаляет, а другой вызывает empty() ?
There was a problem hiding this comment.
сюда мы попадаем из функции cleverGo(). Она и так вся под mutex. При вызове внутри этой функции разве не будет этот mutex распространятся и на вызываемые функции?!
There was a problem hiding this comment.
При вызове внутри этой функции разве не будет этот mutex распространятся и на вызываемые функции
будет
| std::shared_ptr<CarFactory> factory_; | ||
| std::vector<std::unique_ptr<Driver>> DriversOwnedByManagers_; | ||
| static int NumberOfManagers;//TODO �������� ��� � ���� ������ | ||
| std::vector<Driver*> PtrDriversWithCar_; |
There was a problem hiding this comment.
не возникнет проблем с тем, что driver, который хранится в элементе контейнера будет удален, а в контейнере останется null ?
There was a problem hiding this comment.
для этого вроде как pop_back() есть в функции GivePtrDriverWithCar() в предпоследней её строке. Если это не решает проблемы - прошу раскрой где она ещё кроется и натолкни/подскажи решение
There was a problem hiding this comment.
Да, это так. Ты прав такое возможно. Во избежание проблемы поставил std::lock_guardstd::mutex locked(mtx); в функцию, которая работает с std::vector<Driver*> PtrDriversWithCar_; (залил в крайний git push)
Как я вижу это решает проблему. Если нет - прошу указать.
There was a problem hiding this comment.
вопрос: а можно здесь использовать вектор уникальных указателей?! mutex при этом в любом случае нужно ставить в функции, которые работают с этим вектором, но в целом это работу с вектором ещё больше обезопасит.
There was a problem hiding this comment.
вектор умных указателей использовать можно
Lesson_9/SmartPointer/Car.cpp
Outdated
| @@ -0,0 +1,15 @@ | |||
| #pragma once | |||
Lesson_9/SmartPointer/Driver.cpp
Outdated
| #include "CarFactory.h" | ||
| #include "autoschool.h" | ||
|
|
||
| std::mutex mtx; |
There was a problem hiding this comment.
доступ к какому ресурсу синхронизирует этот мьютекс?
There was a problem hiding this comment.
это уже разобрали в переписке в телеграмме. доступ к std::vector<Driver*> PtrDriversWithCar_ - это мембер класса DriverManager
| { | ||
| Driver* p_driverWithCar = myManager_->GivePtrDriverWithCar(); | ||
| this->BuyUsedCar(p_driverWithCar); | ||
| //this->BuyUsedCar(myManager_->GivePtrDriverWithCar()); //same as the two lines above |
There was a problem hiding this comment.
не оставляй ненужных комментариев
There was a problem hiding this comment.
ок. хотел у тебя спросить - строки 50 и 51 в сумме идентичны строке 52?!
There was a problem hiding this comment.
да, myManager_->GivePtrDriverWithCar() можно передать прямо в BuyUsedCar()
| } | ||
| std::unique_ptr<Car> Driver::SellCar() | ||
| { | ||
| return std::unique_ptr<Car> (car_.release()); |
There was a problem hiding this comment.
машину продал, а у менеджера числится как тот, кто все еще может продать?
There was a problem hiding this comment.
не числится, так как есть:
void Driver::BuyUsedCar(Driver* d)
{
car_ = d->SellCar();
std::cout << "I bought a used car\n";
myManager_->GetPtrDriverWithCar(this);
}
просто под покупку бу авто используют отдельную функцию BuyUsedCar. предполагаю что SellCar использовать будут только "свободные" от менеджера Driver'ы.
или есть в чём-то тут проблема?
There was a problem hiding this comment.
на будущее учту
No description provided.