@MaratPetrov96

Где использовать const?

Лабораторную работу по C++ не принимают, т.к. не использовал const везде, где "это имеет смысл". А ещё указывают на отсутствие деструкторов. "Если не выделяете нигде память, выведите в них сообщения о вызове".

Последнее замечание - о вводе.

"В условиях циклов используйте проверки (сделайте, чтобы они возвращали true или false, в зависимости от того, можно ли записать введённое значение в поле данных)

Не обращайте внимание на get и set, т.к. сам не понимаю смысла этого требования.

#pragma once
#include <iostream>
#include <string>
#include <string.h>
#include <stdlib.h>
using namespace std;

const int def_power = 150;
const float def_price = 15.15;
const int def_displacement = 1830;

class Car{
	private:
		char* marka; //марка авто
		int power; //мощность двигателя в кВт
		float cost; //стоимость в тыс. $
		int displacement; //объём двигателя
	public:
		void setMarka(char* m){ //метод записи марки
			marka = m;
		}
		void setPower(int pw){ //метод записи мощности
			power = pw;
		}
		void setCost(float p){ //метод записи стоимости
			cost = p;
		}
		void setDis(int dis){ //метод записи объём двигателя
			displacement = dis;
		}
		std::string getMarka() const { //метод чтения поля марка
		    return marka;
		}
		int getPower() const { //метод чтения поля мощность
			return power;
		}
		float getCost() const { //метод чтения поля стоимость
			return cost;
		}
		int getDis() const { //метод чтения поля объём двигателя
			return displacement;
		}
		~Car(){ //деструктор
			std::cout << "Destructor called for Car of mark " << marka << std::endl;
		}
	public:
		Car(char* m = "Renault", int pw = def_power, float p = def_price, int dis = def_displacement){ //конструктор по умолчанию
			marka = m;
			power = pw;
			cost = p;
			displacement = dis;
		};
	public:
		void Print(){ //вывод параметров на экран
			cout << "Marka is " << getMarka() << endl;
			cout << "Price equals " << getCost() << " thousand $" << endl;
			cout << "Power equals " << getPower() << " kW" << endl;
			cout << "Displacement equals " << getDis() << " cm3" << endl;
		};
		void Input(); //функция ввода параметров, ещё не определена
		};
 
void Car::Input(){ //функция ввода параметров
        char *marka_ = new char[16]; //создаём динамический объект marka
        std::cout << "Input mark: "; //введите марку авто
        std::cin >> marka_;
        setMarka(marka_);
 
		do{
        std::cout << "Input power (kW): "; //введите мощность авто в кВт
        std::cin >> power;
		} while(power <= 0); //мощность не может быть неположительной
        setPower(power);
 
		do{
        std::cout << "Input cost (thousand $): "; //введите стоимости авто в тыс. $
        std::cin >> cost;
		} while(cost <= 0); //стоимость не может быть неположительным
        setCost(cost);

		do{
		std::cout << "Input displacement (cm3): "; //введите объём двигателя в см3
        std::cin >> displacement;
		} while(displacement <= 0); //объём двигателся не может быть неположительным
        setDis(displacement);
		delete marka_;
    };

const int def_truck_power = 700;
const float def_truck_price = 36.0;
const int def_truck_displacement = 2900;
const float def_capacity = 1.8;

class Truck: public Car {
public:
	Truck(
		char* marka, //марка авто
		int power, //мощность двигателя в кВт
		float cost, //стоимость в тыс. $
		int displacement, //объём двигателя,
		float capacity //грузоподъёмность в тоннах
		) : Car(
			marka,
			power,
			cost,
			displacement
		){
			this->capacity = capacity;
		};
private:
	float capacity;
public:
	void setCap(float cap) {
		  capacity = cap;
		}
	float getCap() const{
		return capacity;
	}
	void Print(){ //вывод параметров на экран
		Car::Print();
		cout << "Capacity equals " << getCap() << " tones" << endl;
		};
};


#include "main.h" //подключение заголовочного файла

char* car_name = "Toyota";
const int car_power = 140;
const float car_price = 16.1;
const int car_displacement = 1800;
char* truck_name = "Scania";
const int truck_power = 640;
const float truck_price = 28.1;
const int truck_displacement = 3000;
const float capacity = 2.0;

int main() //главная функция
{
	Car default_; //конструктор по умолчанию, статическое выделение памяти
	Car *example = new Car(car_name,car_power,car_price,car_displacement); //динамическое выделение памяти под объект с параметрами
	Car *example_dynamic = new Car; //конструктор по умолчанию, динамическое выделение памяти
	Truck inherit(truck_name,truck_power,truck_price,truck_displacement,capacity); //объект класса-наследника, статическое выделение памяти
	example->Print(); //вывод параметров нового объекта на экран
	example_dynamic->Print(); //вывод параметров объекта по умолчанию на экран
	delete example; //освобождение памяти
	delete example_dynamic;
	inherit.Print(); //вывод на экран параметров объекта класса-наследника
    default_.Input(); //изменение параметров объекта
	default_.Print();
	system("pause"); //пауза перед завершением программы
    return 0;
}
  • Вопрос задан
  • 201 просмотр
Решения вопроса 1
@12rbah
Ну видимо объявить вместо `char *` `const char *`, где у вас глобальные переменные, и в методах класса, вообще, если строка не должна меняться, её всегда нужно помечать как const.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Mercury13
Программист на «си с крестами» и не только
Это стандартный студенческий код. Можно маленькую ревизию?
1. Класс хранит строки в виде char*, ссылаясь на чужую память, и ничего хорошего не сделано с этой памятью. Подобные ссылки на чужую память хороши как оптимизация, когда практически всегда передаём строковые литералы (например, названия тэгов XML). А так стандартный способ хранить строку — std::string. Ну или char[], если не учили этого.
2. Продолжение 1. С одной стороны, setMarka (например) имеет дело с внешней памятью, которой объект не владеет и которую не надо освобождать. С другой — Input передаёт во владение объекту буфер памяти, который освобождать НАДО.
3. С возвратом true/false — он хорошо сказал. Сам класс должен решать, корректны ли данные.
4. Деструктор — если std::string разрешён, лучше возьми его вместо const char* и забей на деструктор. Если запрещён — либо используй char[], деструктор не нужен. Либо сделай свой string, способный только управлять памятью неизменяемой строки, и деструктор нужен только ему. В промышленном программировании деструкторы редки: либо это реально какая-то необычная структура данных, либо просто компилятор заглючил и нужно хоть пустое, но тело в CPP-файле. Либо идиома pimpl (pointer to implementation, указатель на реализацию), призванная снизить количество каскадных include’ов — а значит, укоротить неполную сборку.
5. char* car_name = "Toyota"; — работает только на очень старых компиляторах. Во всех известных мне строковый литерал имеет тип const char*.
6. Input() должен быть чем-то внешним по отношению к машине: объект «машина» предназначен для хранения данных, и нечего притягивать к нему консоль, которой в программе может и не быть (например, она GUI).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы