21

(14 відповідей, залишених у C)

koala написав:
int min = arr[0];
int min_i = 0;
for(int i=1;i<SIZE;++i)
    if(arr[i] < min) {
        min = arr[i];
        min_i = i;
    }

Для чого змінна min ... якщо не секрет?
min_i як на мене більш ніж достатньо....
Чесно кажучи не раз бачив саме такий приклад в книжках...так і не зрозумів для чого дублювати min...

22

(10 відповідей, залишених у C++)

wander написав:

Якщо у вас немає віртуальних методів, то нащо вам віртуалізація (поліморфізм)?

А якщо , припустимо :

class Base{}
class MyClass : public Base{}

Base* ptr = new MyClass();
delete ptr;

Деструктор MyClass не спрацює....

23

(10 відповідей, залишених у C++)

koala написав:

Щодо деструкторів. Базове правило: деструктор має бути віртуальним завжди, коли використовується посилання на базовий клас.
Якщо в цьому коді зробити

Навіть коли в базовому класі не було віртуальних методів?

24

(15 відповідей, залишених у C++)

Є абстрактний клас CombatVehicle :

class CombatVehicle
{
private:
    std::string  type;
    std::string  model;
protected:
    struct minMax
    {
        double min;
        double max;
    };
    double  health;
    double  last_damage;
    double  last_defence;

public:
    CombatVehicle();
    CombatVehicle(std::string type, std::string model, double health);
    virtual ~CombatVehicle(); 
    bool IsDestroyed() const{ return health <= 0; };
    void ShowShortInfo() const { std::cout << "  " << type << " :  " << model << std::endl; };
    virtual void ShowInfo(int X, int Y, HANDLE handle);
    virtual double Attack() const = 0;
    virtual void   Defense(double damage) = 0;
    std::string getType()const { return type;}
};

Від цього класу наслідуються нащадки Tank , ArmoredCar , AirDefenseVehicle....

lass Tank : public CombatVehicle
{
private:
    double recharge_time;
    double shot_acuracy;
    double armor_thickness;
    static constexpr  minMax rtime     { 1.5 , 2 };
    static constexpr  minMax acuracy   { 2,3 };
    static constexpr  minMax thickness { 30,50 };
    static constexpr  minMax thealth   { 1500,2000 };
    static constexpr const char*  models[5] { "M1A1 Abrams","Leopard","T-64BM Oplot","Merkava","Leclerc" };
public:
    Tank();
    Tank(std::string type, std::string model, double health, double recharge_time,double shot_acuracy,double armor_thickness);
    void   ShowInfo(int X, int Y,HANDLE handle) ;
    double Attack() const { return (100 * shot_acuracy) / recharge_time; }
    void   Defense(double damage); 
};

Існує клас Troops який містить армію техніки в масиві який заповнюється випадковим чином:

class Troops
{
private:
    enum class VehicleType
    {
        Tank = 1,
        ArmoredCar,
        AirDefenseVehicle
    };

    static const size_t max_count              = 10;
    static const size_t min_count              = 5;
    
    std::string name;
    int vehicles_count;
    CombatVehicle** troops;
public:
    Troops();
    ~Troops();
    Troops(std::string name,int vehicles_count);
    bool isVechicleExist() { return vehicles_count > 0; }
    void show(int X, int Y, HANDLE handle) const;
    CombatVehicle& getVehicle() { return *troops[vehicles_count - 1]; };
    void dellCurentVehicle();
    void v_show(int index,int prnt_index,int X, int Y, HANDLE handle) const;
};

Також існує клас Battle який створює дві армії (Troops які в свою чергу генерують випадковим чином екземпляри класів похідних від CombatVehicle  тобто Tank і тд. і зберігають в масиві) і проводить битву двох армій беручи з кожної армії по одному екземпляру техніки ... і так до того моменту коли в одній з армій не закінчиться техніка.

class Battle
{
private:
    Troops troops1;
    Troops troops2;
    int pause = 500;
    bool rаund(CombatVehicle& veh1, CombatVehicle& veh2, HANDLE handle);
    bool isDestroyed(CombatVehicle& veh, HANDLE handle , bool swich);
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
public:
    Battle(std::string tr1name, std::string tr2name,int trvCount, int tr2vCount = 0);
    void battleStart();
};

Саме  про методи CombatVehicle& getVehicle() та  bool rаund(CombatVehicle& veh1, CombatVehicle& veh2, HANDLE handle) було питання....
Все працює ... але виклик  rаund(getVehicle(),getVehicle(),handle) ... якось...

25

(15 відповідей, залишених у C++)

koala написав:
const baseAbstract& get_value(int n) {
  return *arr[n];
}

Саме так я й реалізував...хіба що без const оскільки це не дозволить викликати не константні методи baseAbstract та похідного Myclass. Хоча це не дуже зручно.
Оскільки абстрактний клас не може мати екземпляра то змінну яка приймає значення можна реалізувати тільки так :

  baseAbstract& result = marr.get_value(0);

A оскільки змінна result мусить бути ініціалізована при об'явленні i її не переініцілізувати  то слідуючий код не спрацює:

 baseAbstract& result = marr.get_value(0);
for(int i = 1; i < size; i++)
{
      result = marr.get_value(i);
      result.showInfo();
      result.doWork();
      //............
      //...............
}


Прийшлось так:

void resultProc(baseAbstract& result)
{
      result.showInfo();
      result.doWork();
      //............
      //...............
}

for(int i = 1; i < size; i++)
{
     resultProc(marr.get_value(i))
}

26

(15 відповідей, залишених у C++)

Доброго дня.
Питання.
Наступний код є порушенням інкапсуляції?

class Myclass : public baseAbstract
{
    //---------
    //---------
}
class MyClassArr
{
    private:
        int size;
        baseAbstract** arr = nullptr;
    public:
        MyClassArr(int size):size(size)
        {
            arr = new baseAbstract*[size]{};
            //--------------------
            //--------------------
        }
        ~MyClassArr()
        {
            for(int i = 0;i < size;i++)
                delete arr[i];
            delete[] arr;
        }
        baseAbstract* getMyClass(int n)  //???
        {
            return arr[n];
        }
}

Діло в тому що в подальшому можна написати слідуюче:

MyClassArr marr(6);
baseAbstract * mclass = arr.getMyClass(3);
delete mclass;

В останньому рядку було видалено елемент масиву.... а клас MyClassArr про це навіть не "здогадується"....

27

(21 відповідей, залишених у C++)

Яка різниця з cout?

28

(21 відповідей, залишених у C++)

Дякую.:)

29

(21 відповідей, залишених у C++)

Вивід у консоль Output студії:

#include<windows.h>
.......
.......
OutputDebugStringA("Out of range\n");

Хоча..краще було б в Error List. : )

30

(21 відповідей, залишених у C++)

koala написав:
Олександр Ковальчук написав:
koala написав:

Тобто ваша програма має перевіряти, чи запущений Visual Studio, якось під'єднуватися до неї (можливо, буде потрібен ще й плагін для VS) і передавав ці дані.

Я думав можна якось через

#ifndef DEBUG
/////
/////    
#endif

А казали

Олександр Ковальчук написав:

що таке компіляція і для чого вона потрібна я розумію.

Чому проблема з виводом в консоль студії до мене дійшло...дякую.
Моє питання видалили : (

31

(21 відповідей, залишених у C++)

koala написав:

Це купа геморою - і все виключно заради того, що вам не подобається, в якому вікні виводяться дані?

Діло не в тому що мені не подобається,а в тому що якщо сама программа консольна та ще й з псевдографікою , то виводити туди повідомлення не дуже добре.

32

(21 відповідей, залишених у C++)

wander написав:

Assert'и цілком підпадають під вашу вимогу. Адже:

В assert все влаштовувало окрім того що разом з повідомленням виводиться  вираз який перевіряє assert.

33

(21 відповідей, залишених у C++)

koala написав:

Тобто ваша програма має перевіряти, чи запущений Visual Studio, якось під'єднуватися до неї (можливо, буде потрібен ще й плагін для VS) і передавав ці дані.

Я думав можна якось через

#ifndef DEBUG
/////
/////    
#endif

34

(21 відповідей, залишених у C++)

koala написав:

Ні, не можна (точніше, можна, але вам цього не захочеться). Ви просто не розумієте, що таке компіляція і навіщо вона потрібна.

Ну...я не гуру(поки : )) але що таке компіляція і для чого вона потрібна я розумію.
Вище я писав що повідомлення потрбні в дебаг режимі на етапі відладки.

35

(4 відповідей, залишених у C++)

З вашого дозволу ще одне питяння.
Маю таку конструкцію:

T operator [](int index)
    {
        if (isEmpty() || index > lenght - 1)  return T{};
        return find(index)->data;
    }


Оператор повертає значення елементу списку за його індексом.
У разі коли список пустий чи індекс перевищує кількість елементів в списку він повертає дефолтний конструктор типу(T{}).
І я розумію що це не зовсім хороша ідея,оскільки це працює лише в тому випадку коли T - вказівник і оператор поверне nullptr.
У випадку коли T простий тип (int наприклад) то оператор поверне 0...і не зрозуміло чи це помилка чи значення елементу списку.Як правильно вирішити цю проблему?

36

(21 відповідей, залишених у C++)

Assert'и пробував не те.
Йду "курити" exeptions і loggers...
Дякую .

37

(21 відповідей, залишених у C++)

Саме так в оутпут в який студія виводить попередження і помилки.
Написав List для С++ на основі дунаправленного списку.
Хотілося б в деяких моментах виводити попередження в(дебаг режимі) в консоль студії.
Можливо припиняти виконання + вивід конкретної помилки.

38

(21 відповідей, залишених у C++)

Я майбуть не зовсім коректно сформолював питання....
Малося на увазі не консоль программи, а  Output самої студії.

39

(21 відповідей, залишених у C++)

Підкажіть будь-ласка як можна вивести повідомлення типу awrning, errorу  у консоль студії?

40

(2 відповідей, залишених у C++)

Дякую .
Варіант з частковою спеціалізацією більш ніж підходить.
Йду займатись своїми прогалинами в знаннях шаблонів...:)