Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Lesson_9/SmartPointer/Car.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

#include "stdafx.h"
#include "Car.h"

Car::Car(const std::string& color)
: color_(color)
{
std::cout << color_ << " car has been created\n";
}
Car::~Car()
{ std::cout << color_ << " car has been destroied\n"; }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

мелочь. но старайся сразу писать код в одном стиле (см. размещение фигурных скобок здесь и выше)

void Car::Drive()
{
std::cout << ": "<< color_ << " car in move\n\n";
}
14 changes: 14 additions & 0 deletions Lesson_9/SmartPointer/Car.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once


class Car
{
public:
Car(const std::string& color);
~Car();
void Drive();
void GetCarColor();
private:
std::string color_;
};

9 changes: 9 additions & 0 deletions Lesson_9/SmartPointer/CarFactory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

#include "stdafx.h"
#include "CarFactory.h"
#include "Car.h"

std::unique_ptr<Car> CarFactory::BuildCar(const std::string& color)
{
return std::unique_ptr<Car>(new Car(color));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

можно make_unique

}
10 changes: 10 additions & 0 deletions Lesson_9/SmartPointer/CarFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include "Car.h"

class CarFactory
{
public:
std::unique_ptr<Car> BuildCar(const std::string& color);
};

106 changes: 106 additions & 0 deletions Lesson_9/SmartPointer/Driver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

#include "stdafx.h"
#include "Driver.h"
#include "DriverManager.h"
#include "Car.h"
#include "CarFactory.h"
#include "autoschool.h"


Driver::Driver(const std::string& name, std::shared_ptr<CarFactory> factory)
: factory_(factory)
, name_(name)
{}
void Driver::BuyCar(const std::string& color)
{
car_ = factory_->BuildCar(color);
std::cout << "I bought a new car\n";
myManager_->GetPtrDriverWithCar(this);
}

void Driver::cleverGo()
{
//int whatToDo = rand() % 3 + 1;//dont work with threads
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distrib(1, 2);
int random_number = distrib(gen);

if (car_ != nullptr) //if driver has car - drive
{
std::cout << name_ << " have a car";
car_->Drive();
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}
else
{
std::cout << name_ << "'ll go on foot.... BUT....";
switch (random_number)
{
case 1: //buy a new car
{
this->BuyCar(this->SetCarColor());
std::cout << name_ << " have a car";
car_->Drive();
break;
}
case 2://try to buy used car
{
try
{
Driver* p_driverWithCar = myManager_->GivePtrDriverWithCar();
this->BuyUsedCar(p_driverWithCar);
//this->BuyUsedCar(myManager_->GivePtrDriverWithCar()); //same as the two lines above
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не оставляй ненужных комментариев

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ок. хотел у тебя спросить - строки 50 и 51 в сумме идентичны строке 52?!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да, myManager_->GivePtrDriverWithCar() можно передать прямо в BuyUsedCar()

}
catch (const std::runtime_error& e)
{
std::cout << e.what();
}
break;
}

}
}
}
void Driver::BuyUsedCar(Driver* d)
{
car_ = d->SellCar();
std::cout << "I bought a used car\n";
myManager_->GetPtrDriverWithCar(this);
}
std::unique_ptr<Car> Driver::SellCar()
{
return std::unique_ptr<Car> (car_.release());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

машину продал, а у менеджера числится как тот, кто все еще может продать?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не числится, так как есть:
void Driver::BuyUsedCar(Driver* d)
{
car_ = d->SellCar();
std::cout << "I bought a used car\n";
myManager_->GetPtrDriverWithCar(this);
}

просто под покупку бу авто используют отдельную функцию BuyUsedCar. предполагаю что SellCar использовать будут только "свободные" от менеджера Driver'ы.

или есть в чём-то тут проблема?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не совсем очевидно, ну ладно

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

на будущее учту

}
void Driver::rememberMyManager(DriverManager* myM)
{
this->myManager_ = myM;
}
DriverManager* Driver::sayNameMyManager()
{
return this->myManager_;
}
void Driver::rememberMySchool(autoschool* myS)
{
this->mySchool_ = myS;
}
autoschool* Driver::sayNameMySchool()
{
return this->mySchool_;
}
Driver* Driver::giveDriverToBuyCar()
{
return myManager_->GivePtrDriverWithCar();
}
std::string Driver::SetCarColor()
{
if (name_ == "Sergey")
return "green";
else if (name_ == "Ivan")
return "blue";
else if (name_ == "Sasha")
return "black";
else if (name_ == "Masha")
return "red";
else return "silver";
}
32 changes: 32 additions & 0 deletions Lesson_9/SmartPointer/Driver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include "CarFactory.h"
#include "Car.h"
class DriverManager;
class autoschool;

class Driver
{
public:
Driver(const std::string& name, std::shared_ptr<CarFactory> factory);
void BuyCar(const std::string& color);
void BuyUsedCar(Driver* d);
std::unique_ptr<Car> SellCar();
void Go();
void cleverGo();
std::vector<int> canIbuyUsedCar();
void rememberMyManager(DriverManager* myM);
DriverManager* sayNameMyManager();
void rememberMySchool(autoschool* myS);
autoschool* sayNameMySchool();
Driver* giveDriverToBuyCar();
std::string SetCarColor();
int intRand(const int& min, const int& max);
private:
std::unique_ptr<Car> car_;
std::shared_ptr<CarFactory> factory_;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

почему factory в shared, а manager и school в обычном указателе?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

потому что они никуда и никому не передаются. в данном контексте, по аналогии с factory - можно было использовать shared_ptr для manager и school. Для практики

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а что если удалятся?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я тебя понял. тогда очевидно программа ляжет, так как случится UB. урок данного урока в том что если использовать указатели, то только умные в дальнейшем: shared или unique.

std::string name_;
DriverManager* myManager_;
autoschool* mySchool_;
};

66 changes: 66 additions & 0 deletions Lesson_9/SmartPointer/DriverManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

#include "stdafx.h"
#include "DriverManager.h"
#include "CarFactory.h"
#include "Driver.h"
#include "Car.h"
#include "autoschool.h"
int DriverManager::NumberOfManagers = 0;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ага, была попытка статический член использовать, но он не потребовался. С этого улыбаешься или что-то ещё?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

статические переменные это уже как мемчик )


DriverManager::DriverManager(const std::string& nameManager, std::shared_ptr<CarFactory>& factory)
: factory_(factory)
, nameManager_(nameManager)
{
}
void DriverManager::GetOneDriver(std::unique_ptr<Driver> CurrentDriver)
{
DriversOwnedByManagers_.push_back(std::move(CurrentDriver));
}
void DriverManager::ThreaFunctionManager(int DriverNumber)
{

int i = 4;
while (i)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for в таком случае выглядит очевиднее

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

на будущее принято

{
DriversOwnedByManagers_[DriverNumber]->cleverGo();
std::this_thread::sleep_for(std::chrono::milliseconds(4000));
i--;
}
}
void DriverManager::startThread()
{
std::vector<std::thread> threads;
for (unsigned currentDriverNumber = 0; currentDriverNumber < DriversOwnedByManagers_.size(); ++currentDriverNumber)
{
threads.push_back(std::thread(&DriverManager::ThreaFunctionManager, this, currentDriverNumber));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
for (auto& t : threads)
{
t.join();
}
}
void DriverManager::setFieldManagerToOnedDrivers(int k)
{
DriversOwnedByManagers_[k]->rememberMyManager(this);
}
std::mutex mtx;
void DriverManager::GetPtrDriverWithCar(Driver* NewDriverWhitCar)
{
std::lock_guard<std::mutex> locked(mtx);
PtrDriversWithCar_.push_back(NewDriverWhitCar);
}
Driver* DriverManager::GivePtrDriverWithCar()
{
std::lock_guard<std::mutex> locked(mtx);
if (PtrDriversWithCar_.empty())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

обращение к контейнеру синхронизированно между потоками? не получится, что один записывает/удаляет, а другой вызывает empty() ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

сюда мы попадаем из функции cleverGo(). Она и так вся под mutex. При вызове внутри этой функции разве не будет этот mutex распространятся и на вызываемые функции?!

Copy link
Owner

@Krestol Krestol Jun 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

При вызове внутри этой функции разве не будет этот mutex распространятся и на вызываемые функции

будет

{
throw std::runtime_error ("...tried to buy a used car but they aren�t\n");
}
Driver* p_DriverWithCar = PtrDriversWithCar_.back();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

что если в элементе контейнера окажется nullptr

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

плохо будет, но вроде как логикой программы это непредусмотренно. В какой ситуации это возможно?!

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

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да

PtrDriversWithCar_.pop_back();
return p_DriverWithCar;
}



22 changes: 22 additions & 0 deletions Lesson_9/SmartPointer/DriverManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once
#include "Driver.h"
class autoschool;

class DriverManager
{
public:
DriverManager(const std::string& nameManager, std::shared_ptr<CarFactory>& factory);
void GetOneDriver(std::unique_ptr<Driver> CurrentDriver);
void startThread();
void ThreaFunctionManager(int DriverNumber);
void setFieldManagerToOnedDrivers(int k);
void GetPtrDriverWithCar(Driver* NewDriverWhitCar);
Driver* GivePtrDriverWithCar();

private:
std::string nameManager_;
std::shared_ptr<CarFactory> factory_;
std::vector<std::unique_ptr<Driver>> DriversOwnedByManagers_;
static int NumberOfManagers;//TODO ïîäóìàòü ÷òî ñ ýòèì ðåøèòü
std::vector<Driver*> PtrDriversWithCar_;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не возникнет проблем с тем, что driver, который хранится в элементе контейнера будет удален, а в контейнере останется null ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

для этого вроде как pop_back() есть в функции GivePtrDriverWithCar() в предпоследней её строке. Если это не решает проблемы - прошу раскрой где она ещё кроется и натолкни/подскажи решение

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

см. комментарий выше

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, это так. Ты прав такое возможно. Во избежание проблемы поставил std::lock_guardstd::mutex locked(mtx); в функцию, которая работает с std::vector<Driver*> PtrDriversWithCar_; (залил в крайний git push)
Как я вижу это решает проблему. Если нет - прошу указать.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

вопрос: а можно здесь использовать вектор уникальных указателей?! mutex при этом в любом случае нужно ставить в функции, которые работают с этим вектором, но в целом это работу с вектором ещё больше обезопасит.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

вектор умных указателей использовать можно

};
97 changes: 10 additions & 87 deletions Lesson_9/SmartPointer/SmartPointer.cpp
Original file line number Diff line number Diff line change
@@ -1,93 +1,16 @@
#include <iostream>
#include <string>
#include <memory>

class Car
{
public:
Car(const std::string& color)
: color_(color)
{
std::cout << color_ << " car has been created\n";
}
~Car() { std::cout << color_ << " car has been destroied\n"; }

void Drive()
{
std::cout << color_ << " car in move\n";
}

private:
std::string color_;
};

class CarFactory
{
public:
std::unique_ptr<Car> BuildCar(const std::string& color)
{
return std::unique_ptr<Car>(new Car(color));
}
};

class Driver
{
public:
Driver(const std::string& name, std::shared_ptr<CarFactory> factory)
: factory_(factory)
, name_(name)
{
}

void BuyCar(const std::string& color)
{
car_ = factory_->BuildCar(color);
}

// SellCar
// BuyUsedCar

void Go()
{
if (car_ != nullptr)
{
std::cout << name_ << " I have a car ";
car_->Drive();
}
else
{
std::cout << name_ << ": I'll go on foot\n";
}
}

private:
std::unique_ptr<Car> car_;
std::shared_ptr<CarFactory> factory_;
std::string name_;
};
#include "stdafx.h"
#include "Driver.h"
#include "CarFactory.h"
#include "Car.h"
#include "DriverManager.h"
#include "autoschool.h"

int main()
{
std::shared_ptr<CarFactory> factory(new CarFactory());
Driver driver1("Bob", factory);
driver1.Go();

driver1.BuyCar("red");
driver1.Go();

driver1.BuyCar("blue");
driver1.Go();


Driver driver2("Sam", factory);
driver2.Go();

driver2.BuyCar("red");
driver2.Go();

driver2.BuyCar("blue");
driver2.Go();


std::shared_ptr<CarFactory> factory(new CarFactory());
autoschool mySchool(5, 2, "Ivan",factory);
std::thread thp(&autoschool::threadfuct, &mySchool);
thp.join();
return 0;
}
Loading