Class lenght работа с enum
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Прошу помочь разобраться с классом «Длина». Не пойму, как работать с enum в классе.

Как сделать чтобы величины в
enum einheit {DM,M,KM,FT,YD,MI}
приняли тип дабл? через функцию? и не получается создать конструктор копирования с enum.enum einheit {DM,M,KM,FT,YD,MI}; int main() { Laenge a; //1 m Laenge b(50); //50 m Laenge c(17, YD); //17 Yard
Вывод:
1m, 50m, 17yd
Я попыталась что то придумать, но мне компилятор выдает лишь числа (1 1, 50 1,17 1). Почему 1? так потому что я указала метр=1.
это файл Laenge.cpp
#include"Laenge.h" namespace Programm { Laenge::Laenge() { metr = 1; einheit c = (einheit)M; } Laenge::Laenge(double m, einheit n) { metr = m; einheit n; } double einh(char n) // не работает. Поначалу это было в конструкторе //(Laenge::Laenge(double m, einheit n). { einheit n; switch (n) { case DM: cout << "DM"; break; case KM: cout << "KM"; break; case FT: cout << "FT"; break; case YD: cout << "YD"; break; case MI: cout << "MI"; break; default: cout << "M"; break; } } std::ostream& operator<<(std::ostream& os, Laenge l) { return os << l.metr << " " << //(einheit)l не пойму как указывать; } Laenge::~Laenge() { }
Спасибо!
rrg01, а где файл Laenge.h? Как-то сложно догадаться что там написано ((
И main.cpp тоже хотелось бы целиком посмотреть.
(1) Член перечисления, конечно можно преобразовать в
double
, но это извращение. По стандарту члены перечисления должны иметь интегральный тип (т.е. какой-то из целых типов: int, long, unsigned и т.п.).(2) Конструктора копирования я в коде вообще не вижу.
(3) Формальный текст задания можно посмотреть? Не совсем понятно что ты пытаешься сделать.
(4) Нормально оформить исходный код в посте у тебя опять не получилось (( Читай ещё раз:
Три символа перед cpp (
cpp
— это пометка языка, можно не указывать) — это обратные апострофы. На клавиатуре этот символ обычно располагается на той же кнопке, что и тильда (~).Вот main(), где естественно, менять ничего нельзя.
#include <iostream> #include "Laenge.h" using namespace std; using Programm::Laenge; enum einheit {DM,M,KM,FT,YD,MI}; int main() { Laenge a; //1 m Laenge b(50); //50 m Laenge c(17, YD); //17 Yard try { Laenge d(-5); //-5 m } catch (...) { cout << "Отрицательная длина!" << endl; } cout << a << ", " << b << " = " << b.umrechnen(DM) << "dm, " << c << endl; //b.umrechnen(DM) -> функция, которая будет конвертировать величины, этого я пока не ////делала, так как сперва хочу понять работу с enum. try { cout << b+a-c << endl; cout << b-2*Laenge(1,YD)*0.25 << endl; cout << a-c << endl; } catch (...) { cout << "Отрицательная длина!" << endl; } try { a = (Laenge(10,MI)*0.5-2*(Laenge(2,KM)+Laenge(17,YD))); // оператор умножения на цифру, //и цифру на Laenge;это я тоже пока что оставила. a.konvertieren(M); cout << a << endl; a = a*(-2); } catch (...) { cout << "Отрицательная длина!" << endl; } Laenge arr[] = {Laenge(1,DM), Laenge(1,FT), Laenge(1,YD)}; Laenge::minimum(arr,3) = Laenge(1,MI); // static Laenge& minimum(Laenge[], int); Laenge::minimum(arr,3) = Laenge(1); for (int i=0; i<3; ++i) cout << arr[i] << endl; return 0; } Вывод: Отрицательная длина! 1m, 50m = 500dm, 17yd 35.4552m 49.5428m Отрицательная длина! 4015.61m Отрицательная длина! 1mi 1m 1yd
**Laenge.h** #pragma once #include <iostream> using namespace std; namespace Programm { class Laenge { double metr; enum einheit { DM, M, KM, FT, YD, MI }; public: Laenge(); Laenge(double, einheit); Laenge(const Laenge& l); Laenge (Laenge& l); friend std::ostream& operator<<(std::ostream& os, Laenge& l); ~Laenge(); }; }
**Laenge.cpp** #include "Laenge.h" namespace Programm { Laenge::Laenge() { metr = 1; einheit c = (einheit)M; } Laenge::Laenge(const Laenge& l) { metr = l.metr; einheit l; } Laenge::Laenge(double m, einheit n) { metr = m; einheit n; switch (n) { case DM: cout << "DM"; break; case KM: cout << "KM"; break; case FT: cout << "FT"; break; case YD: cout << "YD"; break; case MI: cout << "MI"; break; default: cout << "M"; break; } } std::ostream& operator<<(std::ostream& os, Laenge& l) { return os << l.metr << " " << (einheit)l; } Laenge::~Laenge() { } }
Спасибо за подсказку оформления!
Набирала все вручную, не могла понять что не так) Теперь все ясно
Подробно посмотрю вечером, но несколько замечаний сразу.
(1) Дублирование определения
enum einheit {DM,M,KM,FT,YD,MI}
в main.cpp и классеLaenge
. Причём первое доступно глобально, но только в main.cpp. А второе доступно только внутри классаLaenge
, поскольку описано какprivate
(неявно). Решение: в Laenge.h вынести в глобальную область видимости, в main.cpp убрать определение и прописатьusing Programm::einheit
.(2) Класс должен быть описан так:
enum einheit { DM, M, KM, FT, YD, MI }; // здесь определяется новый тип class Laenge { double metr; einheit unit; // тип переменной einheit public: Laenge(); Laenge(double, einheit); Laenge(const Laenge& l); // ...остальные методы... friend std::ostream& operator<<(std::ostream& os, Laenge& l); friend Laenge operator + (const Laenge& lho, const Laenge& rho); // ...остальные операторы... // деструктор для этого класса вообще не нужен };
(3) Конструктор копии:
Laenge::Laenge(const Laenge& l) { metr = l.metr; unit = l.unit; }
Остальные — сама додумаешь.
(4) Из конструктора
Laenge::Laenge(double m, einheit n)
убратьswitch
.(5) Оператор
std::ostream& operator<<(std::ostream& os, Laenge& l)
сделать так:const char **unit_labels = { "dm", "m", "km", "ft", "yd", "mi" }; std::ostream& operator<<(std::ostream& os, const Laenge& l) { return os << l.metr << unit_labels[(int)l.unit]; }
Коротко: Считай, что тип-перечисление (
enum
) — это ограниченный набор именованных целых констант. Первая константа в наборе (по умолчанию) имеет значение 0. Каждая следующая константа (по умолчанию) имеет значение на 1 больше предыдущей. Переменные типа-перечисления можно сравнивать и приводить к числовому типу.Попробуй сделать то, что я написал. Исходники и вопросы выкладывай — посмотрим что получилось.
Про enum я уже многое прочла, и использовать вне класса могу. Но в данном случае, не совсем понимаю.
К сожалению не разрешается по заданию использовать глобальные переменные.
Я все же попробовала по вашему методу усовершенствовать прг. Но к сожалению он выдает ошибку.
далее я изменила её так вот:
**Laenge.cpp** #include "Laenge.h" namespace Programm { Laenge::Laenge() { metr=1; einheit c = (einheit)M; } Laenge::Laenge(int m, einheit n) { metr = m; unit = n; } Laenge::Laenge(const Laenge& l) { metr = l.metr; unit = l.unit; } //const char **unit_labels = { "DM", "M", "KM", "FT", "YD", "MI"}; std::ostream& operator<<(std::ostream& os, const Laenge& l) { os << l.metr << " "; switch (l.unit) { case 0: os << "DM"; break; case 2: os << "KM"; break; case 3: os << "FT"; break; case 4: os << "YD"; break; case 5: os << "MI"; break; default: os << "M"; break; } os << l.unit; return os; } }
**Laenge.h** #pragma once #include <iostream> using namespace std; namespace Programm { class Laenge { public: enum einheit { DM, M, KM, FT, YD, MI }; Laenge(); Laenge(int, einheit); Laenge (const Laenge& l); friend std::ostream& operator<<(std::ostream& os, const Laenge& l); private: int metr; einheit unit; }; }
Но он выдает такую вот Ошибку:
Ошибкa C2664 «Programm::Laenge::Laenge(const Programm::Laenge &)»: невозможно преобразовать аргумент 2 из «einheit» в «Programm::Laenge::einheit» class_laenge
И как я понимаю ошибка здесь:
Laenge::Laenge(int m, einheit n)
{
metr = m;
unit = n; // Ошибка. но почему?
}
(1) См. п.1 предыдущего поста.
На этом ты ошибку и словила. Потому что у тебя в программе одновременно существуют
::einheit
(глобальный) иProgramm::Laenge::einheit
(определённый в классе). Так не надо делать.Возвращаясь к моему совету. Есть одна тонкость. Если
einheit
определить в Laenge.h в глобальном пространстве имён, то проблем нет. Еслиeinheit
определить в Laenge.h в пространстве имёнProgramm
, то в main.cpp придётся либо импортировать все члены перечисления по отдельностиusing Programm::DM; using Programm::M; using Programm::KM; using Programm::FT; using Programm::YD; using Programm::MI;
либо квалифицировать каждую константу при использовании пространством имён например
Laenge c(17, Programm::YD); //17 Yard
либо подтягивать в main.cpp всё пространство имён
Programm
using namespace Programm;
Подтянуть имена констант, подтянув название типа перечисления, как я написал раньше, не получится. Стандарт ISO/IEC 14882:2011 п.7.3.3.1:
(2) Если main.cpp изменять нельзя от слова «совсем», то формулировка задания некорректна. Определение
einheit
должно быть (а) либо в Laenge.h, (б) либо в отдельном заголовочном файле, который включается и в main.cpp, и в Laenge.h, (в) либо Laenge.h вместе с Laenge.cpp должны быть в main.cpp (одним файлом).(3) Кстати ещё по поводу корректности задания. Интересный момент:
cout << b+a-c << endl; // вывод: 35.4552m
a
иb
заданы в метрах,c
— в ярдах. Почему результат получается в метрах, а не в ярдах? А если написатьc + c
, то результат тоже будет в метрах?Или ещё:
a = (Laenge(10, MI)*0.5 - 2 * (Laenge(2, KM) + Laenge(17, YD))); a.konvertieren(M);
Метод «конвертирен», на сколько я понимаю, должен сконвертировать переменную
a
в метры. Хорошо. А в результате выполнения предыдущей строки, дляa
какие единицы будут установлены?(4) Глобальные переменные я не предлагал использовать. Определение перечисления — это определение нового типа данных, такое же, как определение класса или структуры.
(5) После тупого разглядывания
main()
, у меня появилась мысль, что в классLaenge
неплохо бы добавить ещё один член:private: double metr; // длина МЕТРАХ double len; // длина в единицах, указанных в unit einheit unit; // единицы длины
Все вычисления проводить в метрах, а вывод показывать в тех единицах, которые заданы. Мне кажется так удобнее, чем держать матрицу коэффициентов для пересчёта одних единиц в другие.
(6) Кстати, длину нужно хранить таки в
double
, а не вint
. А то так переведешь футы в метры и обратно... ))