Показать полную графическую версию : Перегрузка констуктора
Как правильно перегружать конструктор? Помогите, не понятно.
#include <iostream>
class Date
{
public:
Date(int, int);
Date(int, int, int);
void print() const;
void setDate(int, int, int);
private:
int day;
int month;
int year;
};
Date::Date(int dd, int mm, int yyyy)
{
day = dd;
month = mm;
year = yyyy;
}
void Date::setDate(int dd, int mm, int yyyy)
{
day = dd;
month = mm;
year = yyyy;
}
void Date::Date(int dd, int yyyy)
{
day = dd;
year = yyyy;
}
void Date::print() const
{
std::cout << day << "/" << month << "/" << year << std::endl;
}
int main()
{
setlocale(LC_ALL,".1251");
Date d(2,2,2000);
Date d2(1,1991);
d.print();
d2.print();
system("pause");
return 0;
}
ха сам додумался
лишнем было
void Date::Date(int dd, int yyyy)
{
day = dd;
year = yyyy;
}
и как раз назрело еще два вопроса:
1) Как перегрузить print() что бы она понимала автоматически сколько ей печатать параметров?
2) Как перегрузить Date() c типом char?
хо хо хо сам решил!
вот:
class Date
{
public:
Date(int, char *, int);
Date(int, int);
Date(int, int, int);
void print() const;
void printChar() const;
void setDate(int, int, int);
private:
int day;
int month;
char *_month;
int year;
};
Date::Date(int dd, char *mm, int yyyy)
{
day = dd;
_month = mm;
year = yyyy;
}
El Scorpio
16-07-2010, 05:54
Date::Date(int dd, char *mm, int yyyy)
{ day = dd; _month = mm; year = yyyy; }
»
Неправильно.
Представь,*что дальше в тексте программы будет команда на освобождение области памяти, на которую указывает mm. Тогда попытка обратиться к _month приведёт к ошибке.
И вообще, использовать char* нельзя. Для работы с текстом нужно объявлять объекты строковых контейнеров (string, AnsiString и т.д.)
Glareone
16-07-2010, 19:40
И вообще, использовать char* нельзя. »
Date::Date(int dd, char *mm, int yyyy)
{ day = dd; _month = mm; year = yyyy; } »
В данном примере, действительно, так лучше не делать.Но вообще, использовать char* не запрещает никто. Просто за выделением памяти mm=new... delete[] mm; самому приходится следить.
ещё пара советов по оптимизации: исхожу из предположений
1) последовательность уточнения даты: год, месяц, день, час, минута, секунда, либо в обратном порядке. Т.е. нет смысла задавать дату днём и годом (без указания месяца).
2) обратный порядок нужен только для того, чтобы сокращённо задавать промежуток времени (например интервал 1 день 5 секунд). А его лучше задавать количеством секунд, а не датой. Поэтому обратный порядок тоже не нужен.
// Таким образом нужен один конструктор:
class Date {
public:
Date(int year=0, int month=1, int day = 1, int hour=0, int min=0, int sec=0);
...
private:
_hidden_init(); // не раскрывается inline
};
// т..к. по сути мы даём возможность заполнить структуру, то лучше вынести inline
// так мы разделим присвоение параметров (как бы inline) и дальнейшую обработку _hidden_init()
inline Date::Date(...)
{
...
_hidden_init();
}
Если нужно иногда использовать время отдельно от даты, то можно сделать так:
// Таким образом нужен один конструктор:
class Time {
public: Time(int h, int m, int s);
};
class Date {
public: Date(int y, int m, int d);
};
class DateTime
{
public:
DateTime(const Date&, const Time&);
DateTime(const Date&);
DateTime(const Time&);
};
// тогда путаницы не возникнет
pva, Он до этого дойдёт позже. :) В книге Дейтелов изучение классов начинается с самых простых примеров без проверки на ошибки и только чуть-чуть погодя будут этот класс Time улучшать, добавляя функции проверки, коррекции и т.д.
pva, это я догоняю. Мне надо, например, перегрузить вот так: ДАТА(01 01 1900) и ДАТА( 1 января 1900). Не пойму пока как это сделать "правильно".
и вопрос:
если написать _hidden_init(); то конструктор перестает быть по умолчанию "встраиваемый" и будет "вызываться"?
и что бы он стал inline это надо явно указывать? я правильно понимаю?
Нашел такое решение:
#include <iostream>
class Date
{
public:
Date(int, char, int);
Date(int, int, int);
void print() const;
void printChar() const;
void setDate(int, int, int);
private:
int day;
int month;
int year;
};
Date::Date(int dd, int mm, int yyyy)
{
day = dd;
month = mm;
year = yyyy;
}
Date::Date(int dd, char mm, int yyyy)
{
day = dd;
month = mm;
year = yyyy;
}
void Date::setDate(int dd, int mm, int yyyy)
{
day = dd;
month = mm;
year = yyyy;
}
void Date::print() const
{
if(month >= 0)
std::cout << day << "/" << month << "/" << year << std::endl;
else
std::cout << day << "/" << year << std::endl;
}
void Date::printChar() const
{
std::cout << day << "/" << char(month) << "/" << year << std::endl;
}
int main()
{
setlocale(LC_ALL,".1251");
char _month[]="январь";
Date d(2,12,2000);
std::cout << _month[0] << std::endl;
Date d3(1, _month[0],1991);
d.print();
d3.printChar();
system("pause");
return 0;
}
только вот одна проблема:
в Date могу передать только одну букву названия месяца.
Так что думаю тут без * никак так как надо передавать массив. Или есть другой "правильный путь"?
Так что думаю тут без * никак так как надо передавать массив. Или есть другой "правильный путь"? »Правильно. Используй символьный массив указателей. Я когда-то решал подобную задачу.
Date.h
// Определение класса Time
// Функции-члены определены в Date1.cpp
// Процессорные директивы, которые предотвращают
// многократное включение заголовочного файла
#ifndef DATE_H
#define DATE_H
class Date{
public:
// конструктор
Date(int = 1, int = 1, int = 1990);
// печать дат в формате месяца/дня/года. 05.01.1997
void print() const;
// печать дат в формате число, срока названия месяца, год. 5 января 1997 год.
void print_Day_StringMonth_Year() const;
~Date();
// функцияи 'set' Установка и проверка вводимых параметров
void setDate(int, int, int); // установка дня, месяца, года
private:
int day; // День от 1 - 31
int month; // Месяц от 1 - 12
int year; // Год. Целое число
// функция-утилита для проверки соответствия дня месяца и году
int checkDay(int); // На всякий случай ;)))))
};
#endif
Date.cpp
// определения функции-членов класса Date
#include <iostream.h>
using std::cout;
using std::endl;
#include "date.h"
// конструктор: поддержка соответствующего значения месяца;
// вызвать функцию-утилиту checkDay для поддержки соответствующего
// значения дня
Date::Date(int dy, int mn, int yr)
{
setDate(dy, mn, yr); // Функция правильной установки дня, месяца, и года
}
// печать объекта Date в форме месяца/дня/года. 05.01.1997--------------------
void Date::print() const
{
int NumbNullDay_and_Month, // Счётчик
NumbNull_Day, // индекс для массива NumberDay_Month, для правильного отображения числа ДНЯ с нулём
NumbNull_Month; // индекс для массива NumberDay_Month, для правильного отображения числа МЕСЯЦА с нулём
static const char *NumberDay_Month [10] = {"", "01", "02", "03", "04", "05", "06", "07", "08", "09"};
// Проверка дня, если в числе ДНЯ один разряд, вычислить соответствующий индекс массива NumberDay_Month...
if(day < 10){
for(NumbNullDay_and_Month = 0; NumbNullDay_and_Month < 11; NumbNullDay_and_Month++){
if(NumbNullDay_and_Month == day)
NumbNull_Day = NumbNullDay_and_Month;
}
}
// Если в числе ДНЯ, больше одного разряда, то присвоить переменной NumbNull_Day, тоже число, что и было
else if(day > 9)
NumbNull_Day = day;
// Проверка дня, если в числе МЕСЯЦА один разряд, вычислить соответствующий индекс массива NumberDay_Month...
if(month < 10){
for(NumbNullDay_and_Month = 0; NumbNullDay_and_Month < 11; NumbNullDay_and_Month++){
if(NumbNullDay_and_Month == month)
NumbNull_Month = NumbNullDay_and_Month;
}
}
// Если в числе МЕСЯЦА, больше одного разряда, то присвоить переменной NumbNull_Day, тоже число, что и было
else if(month > 9)
NumbNull_Month = month;
// Вывод вариантов
if(day < 10 && month < 10) // Если в ДНЕ И в МЕСЯЦЕ число меньше десяти
cout<<NumberDay_Month[NumbNull_Day]<<"."<<NumberDay_Month[NumbNull_Month]<<"."<<year<<endl;
else if(day < 10 && month > 9) // Если в ДНЕ меньше деСяти, И в МЕСЯЦЕ больше деВяти
cout<<NumberDay_Month[NumbNull_Day]<<"."<<NumbNull_Month<<"."<<year<<endl;
else if(day > 9 && month < 10) // Если в ДНЕ больше деВяти, И в МЕСЯЦЕ больше деСяти
cout<<NumbNull_Day<<"."<<NumberDay_Month[NumbNull_Month]<<"."<<year<<endl;
else if(day > 9 && month > 9) // Если в ДНЕ И в МЕСЯЦЕ число больше деСяти
cout<<NumbNull_Day<<"."<<NumbNull_Month<<"."<<year<<endl;
}
// печать дат в формате число, строка названия месяца, год--------------------
void Date::print_Day_StringMonth_Year() const
{
int i;
static const char *Month [13] = {"", "Yanvaria", "Fevralia", "Marta", "Aprelia",
"May", "Yuni", "Yuli", "Avgusta", "Sentyabria",
"Ortyabria", "Noyabria", "Dekabria"};
for(i = 0; i < 14; i++){
if(month == i)
cout<<day<<" "<<Month[i]<<" "<<year<<" God."<<endl;
}
}
// функция-утилита для поддержки соответствующего
// значения дня в зависимости от месяца и года.
// является ли 2000-й год високосным?-----------------------------------------
int Date::checkDay(int testDay)
{
static const int daysPerMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(testDay > 0 && testDay <= daysPerMonth[month])
return testDay;
if(month == 2 && // февраль: проверка високосноо года
testDay == 29 &&
(year % 400 == 0 || (year %4 == 0 && year % 100 != 0)))
return testDay;
cout<<" DENY: "<<testDay<<" NEPRAVILNIY. USTANOVITY DENY 1 \n\n";
print();
print_Day_StringMonth_Year();
return 1; // если значение неправильное
}
// Проверка и Установка даты через setDate------------------------------------
void Date::setDate(int dy, int mn, int yr)
{
if(mn > 0 && mn <= 12) // проверка месяца
month = mn;
else{
month = 1;
cout<<" MEZYAC: "<<mn<<" NEPRAILNIY. USTANOVITY MEZYAC 1. \n\n";
}
year = yr;
day = checkDay(dy); // проверка дня
print();
print_Day_StringMonth_Year();
cout<<"\n KONSTRUKPOR OBEKTA 'DATE'\n";
cout<<endl;
}
// деструктор-----------------------------------------------------------------
Date::~Date()
{
cout<<" DESTRUKTOR DATE-OBEKTA DLA DATY ";
print();
cout<<endl;
}
//---------------------------------------------------------------------------
// демонстрация композиции: объект с объектами-членами
#include <iostream.h>
using std::cout;
using std::cin;
using std::endl;
#include "date.h"
int main()
{
int dayy,
monthh,
yearr,
z;
Date d(3, 12, 1988);
cout<<'\n';
// Формат 05.01.1997
d.print();
cout<<'\n';
// Формат 5 января 1997 года.
d.print_Day_StringMonth_Year();
cout<<"\n PROVERKA KONSTRUKTORA 'DATE' S NEPRAVILYNIVI ZNACHENIAVI: \n";
Date dd(14, 35, 1994); // неправильные Date-значения
cout<<endl;
do{
cout<<"\n Enter '0' START AND '-1' FINISH: ";
cin>>z;
cout<<endl;
// Ввод нужных значений
cout<<"Enter Day: ";
cin>>dayy;
cout<<"Enter Month: ";
cin>>monthh;
cout<<"Enter Year: ";
cin>>yearr;
// Функция установки и проверки правильности ввода
d.setDate(dayy, monthh, yearr);
// Вывод вариантов отображения
d.print();
d.print_Day_StringMonth_Year();
}
while(z != -1);
cin>>z;
return 0;
}
//---------------------------------------------------------------------------
El Scorpio
21-07-2010, 01:45
Так что думаю тут без * никак так как надо передавать массив. Или есть другой "правильный путь"? »
Для работы со строками нужно использовать классы строковых контейнеров. Управляться с "символьными массивами" под силу только профессионалам, ибо там легко допустить ошибку,*которая сделает программу неработоспособной.
#include <strings.h>
class Date
{
public:
Date (int, const string &, int);
Date(int, int);
Date(int, int, int);
void print() const;
void printChar() const;
void setDate(int, int, int);
private:
int Fday;
int Fmonth;
string Fsmonth;
int Fyear;
};
Date::Date(int dd, const string &mm, int yyyy)
{
Fday = dd;
year = yyyy;
Fmonth = mm; // копирование строки выполняется переопределённым оператором класса
}
В Borland C++ Builder для работы со строками обычно используется класс AnsiString
Опять же, нет нужды хранить строковое значение месяца в объекте - ведь названия месяцев известны :)
не знаю, по моему это сложнее, т.к. я до первого додумался первее и сам.
P.S.
в MVS надо использовать <string>
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.