View Full Version : c++, кто-нить знает?
Prosto_tak
09-02-2006, 23:35
Опять мне надо домашку сделать, но я чет вааще ниче не понимаю, есть тут знатоки C++, которые могли бы помочь? :shuffle:
Во, блин, вопрос.... :D
Ну, знаю...
Но школьные задания писать не буду. ;)
А... дочитался, что тут именно домашку и надо... сорры
Prosto_tak
09-02-2006, 23:39
Ну там немногааа...
Tee luokka koirasta, jossa on tiedot koiran nimestä, rodusta ja syntymävuodesta. Määrittele merkkimuotoiset tietojäsenet stringeiksi.
Koiran nimi ja rotu muokataan aina siten, että ylimääräiset välilyönnit poistetaan sanan edestä väleistä ja lopusta. Suurten ja pienten kirjainten muutos C++:lla on hiukan hankalaa, joten sitä ei tarvitse tehdä. Tee Koira-luokkaan muokkaa metodi, joka muokkaa edellisellä tavalla merkkijonon. Tee lisäksi luokkaan muodostimet, hajotin, sijoitusoperaattori ja metodit.
Еще и по-фински :gy: не... нафик-нафик... я спать хочу =)
Prosto_tak
09-02-2006, 23:42
Могу по русски написать?
Я понял тока что ко всему прочему надо еще конструктор и деструктор создать :gy:
Я Яву знаю, C++ знаю, я финского не знаю :)
Могу по русски написать?
Напиши.
Я уже ужин дожевываю... ;)
Prosto_tak
09-02-2006, 23:48
Сейчас переведу, погодите :)
Prosto_tak
09-02-2006, 23:57
создать класс Собак, в которой определены кличка (koiran nimi), порода (rotu), год рождения (s.vuosi). эти переменные надо определить как "строки" string.
в кличке и породе надо сделать так что пробелы вначале конце и внутри удаляются. на больших и маленьких буквах не заморачиваться, так как оно гиморно в С++.
сделать метод которым можно редактировать класс Собака, который по указанному выше редактирует символьные переменные
В добавок сделать конструктор, деструктор, методы и sijoitusoperaattori - не знаю как перевести
Prosto_tak
10-02-2006, 00:00
Еще дается такой код, которым якобы можно тестировать класс-СОБАКА и написанно что надо дополнить отсутствующие коды подклассов -
-----------
#include <iostream>
#include <string>
using namespace std;
#include "Koira.hpp"
// palauttaa arvonaan uuden Koira-olio, jonka tiedot
// on pyytanyt kayttajalta
Koira * luoKoira() ;
// palauttaa arvonaan paikallisen Koira-olion
// koiran tiedot viedaan parametreina nimi, rotu ja vuosi
Koira luoKoira(char *, char *, int);
int main()
{
Koira *p;
Koira koira;
cout <<"\nOletusmuodostin koira:\n " << koira;
p = luoKoira();
cout <<"\nluoKoira-metodin koira:\n" << *p;
Koira *q = new Koira (*p);
cout <<"\nKopiointimuodostin koira:\n" << *q;
koira = luoKoira
(" iitu "," paimensukuinen suomen lapinkoira ", 1988);
cout <<"\nluoKoira(char*, char*, int) -metodin koira:\n"<<koira;
Koira koira2;
koira2 = *p + *q;
cout <<"\n*p + *q koira: \n" << koira2;
Koira koira3;
koira3 = koira2++;
cout <<"\n"<<koira3 <<" != " << koira2;
koira3 = ++koira2;
cout <<"\n"<<koira3 <<" = " << koira2;
delete p;
delete q;
cout <<"\n\n**LOPPU***\n";
cin.ignore()
return 0;
}
--------------
sijoitusoperaattori - оператор присваивания
Prosto tak, где Вы учитесь?
Nu, tak ego mozhno ob'javit', naprimer
class Sobak{
private:
string nimi;
string rotu;
string vuosi;
public:
// konstructor
Sobak();
// kostruktor so znachenijami (esli nado)
Sobak(string /*name*/, string /*breed*/, string /*year*/);
// destruktor
~Sobak();
void setName(string name);
string getName(void);
void setBreed(string name);
string getBreed(void);
void setYear(string name);
string getYear(void);
};
Prosto_tak
10-02-2006, 00:17
ZUBER, спасибо!
Еще вопросик, я могу заменять английские значения на финские?
Sobak(string /*nimi*/, string /*rotu*/, string /*svuosi*/);
void setNimi(string name);
string getName(void);
void setRotu(string name);
string getRotu(void);
void setSvuosi(string name);
string getSvuosi(void);
};
Ну, знак равно я потом добаллю :)
Конечно. Оно есть имена переменных .
Prosto_tak
10-02-2006, 00:24
ZUBER, еще вопросик, а как сделать чтобы в кличке и породе пробелы вначале, конце и внутри слова удалялись?
Prosto_tak
10-02-2006, 00:26
void setNimi(string name);
string getName(void);
void setRotu(string name);
string getRotu(void);
void setSvuosi(string name);
string getSvuosi(void);
};
а выделенные болдом name так и будут, т.е. они остаются неизменными?
#include <string>
#include <iostream>
using namespace std;
class Sobak{
private:
string nimi;
string rotu;
string vuosi;
public:
// konstructor
Sobak();
// kostruktor so znachenijami (esli nado)
Sobak(string /*name*/, string /*breed*/, string /*year*/);
// destruktor
~Sobak();
void setName(string name);
string getName(void);
void setBreed(string name);
string getBreed(void);
void setYear(string name);
string getYear(void);
// debug
void printMe(void);
};
Sobak::Sobak(){
// nothing
nimi = "";
rotu = "";
vuosi = "";
}
Sobak::~Sobak(){
// nothing
}
Sobak::Sobak(string name, string breed, string year){
nimi = name;
rotu = breed;
vuosi = year;
}
void Sobak::setName(string name){
nimi = name;
}
string Sobak::getName(void){
return nimi;
}
void Sobak::setBreed(string breed){
rotu = breed;
}
string Sobak::getBreed(void){
return rotu;
}
void Sobak::setYear(string year){
vuosi = year;
}
string Sobak::getYear(void){
return vuosi;
}
void Sobak::printMe(void){
cout << " sobak:" << nimi << "|" << rotu << "|" << vuosi << "\n";
}
int main(void){
Sobak *x= new Sobak();
Sobak *y= new Sobak(" doggy "," stupid ","1980");
x->printMe();
y->printMe();
delete(y);
delete(x);
return 0;
}
Vot proga, kotoraja bez znaka = i bez obrezanija probelov, poka
void setNimi(string);
string getName(void);
void setRotu(string );
string getRotu(void);
void setSvuosi(string );
string getSvuosi(void);
};
а выделенные болдом name так и будут, т.е. они остаются неизменными?
Mozhno dazhe tak. V opredelenii klassa ne obyazatel'no ukazyvat' imena peremennyh, tol'ko tipy.
#include <string>
Sobak *y= new Sobak(" doggy "," stupid ","1980");
Зуб, собаки стока не живут :)
Prosto_tak
10-02-2006, 00:40
кстати, мы вроде делали всю фигню в двух файлах, т.е. sobak.hpp & sobak.cpp
получается в sobak.hpp у меня идет: ?
---
#ifndef KOIRAHPP
#define KOIRAHPP
class Koira
{
private:
string nimi;
string rotu;
string vuosi;
public:
// oletusmuodostin - konstruktor
Koira();
// tai param.muodostin -kosntruktor
Koira(string /*name*/, string /*breed*/, string /*year*/);
// hajotin - destruktor
~Koira();
//sij.operaattori
Koira &operator=(const Koira &);
void kysy(); //void sprosit_dannye();
void nayta(); //void pokazat_dannye();
void setNimi(string );
string getNimi(void);
void setRotu(string );
string getRotu(void);
void setSvuosi(string );
string getSvuosi(void);
};
#endif
Prosto_tak
10-02-2006, 00:43
А остальное в KOIRA.CPP ?
#include "koira.hpp"
#include <iostream>
// oletusmuodostin
Sobak::~Sobak(){
// nothing
}
Sobak::Sobak(string name, string breed, string year){
nimi = name;
rotu = breed;
vuosi = year;
}
void Sobak::setName(string name){
nimi = name;
}
string Sobak::getName(void){
return nimi;
}
void Sobak::setBreed(string breed){
rotu = breed;
}
string Sobak::getBreed(void){
return rotu;
}
void Sobak::setYear(string year){
vuosi = year;
}
string Sobak::getYear(void){
return vuosi;
}
void Sobak:rintMe(void){
cout << " sobak:" << nimi << "|" << rotu << "|" << vuosi << "\n";
}
int main(void){
Sobak *x= new Sobak();
Sobak *y= new Sobak(" doggy "," stupid ","1980");
x->printMe();
y->printMe();
delete(y);
delete(x);
return 0;
}
да, я в один файл для быстроты. Сейчас смотры, как строку резать :)
Prosto_tak
10-02-2006, 00:55
Zuber, у тебя есть msn или icq?
Зубер, у тебя есть мсн или ицq?
ИЦQ на Wиндах есть, но я сейчес везде линух гоняю. Слишком много вирусов стало кругом
Prosto_tak
10-02-2006, 01:00
А можешь БОЛДОМ выделить те места, где задается обрезание пробелов в словах?
Усе, финал версион :)
#include <string>
#include <iostream>
using namespace std;
class Sobak{
private:
string nimi;
string rotu;
string vuosi;
public:
// konstructor
Sobak();
// kostruktor so znachenijami (esli nado)
Sobak(string /*name*/, string /*breed*/, string /*year*/);
// destruktor
~Sobak();
void setName(string name);
string getName(void);
void setBreed(string name);
string getBreed(void);
void setYear(string name);
string getYear(void);
Sobak &operator=( Sobak & );
// debug
void printMe(void);
private:
string cutString(string);
};
Sobak::Sobak(){
// nothing
nimi = "";
rotu = "";
vuosi = "";
}
Sobak::~Sobak(){
// nothing
}
Sobak::Sobak(string name, string breed, string year){
this->setName(name);
this->setBreed(breed);
this->setYear(year);
}
void Sobak::setName(string name){
nimi = cutString(name);
}
string Sobak::getName(void){
return nimi;
}
void Sobak::setBreed(string breed){
rotu = cutString(breed);
}
string Sobak::getBreed(void){
return rotu;
}
void Sobak::setYear(string year){
vuosi = year;
}
string Sobak::getYear(void){
return vuosi;
}
string Sobak::cutString(string daInput){
int counter = 0;
char cur_pos = ' ';
string _tmp = daInput;
while((cur_pos == ' ')&&(counter<_tmp.length())){
cur_pos = _tmp[counter];
if(cur_pos == ' ')
counter++;
}
_tmp.erase(0,counter);
counter = 0;
cur_pos = ' ';
while((cur_pos == ' ')&&(counter>=0)){
cur_pos = _tmp[_tmp.length() - counter - 1];
if(cur_pos == ' ')
counter++;
}
if(counter > 0)
_tmp.erase(_tmp.length() - counter,counter);
return _tmp;
}
void Sobak::printMe(void){
cout << " sobak:" << nimi << "|" << rotu << "|" << vuosi << "\n";
}
Sobak &Sobak::operator=(Sobak &_sobak){
nimi = _sobak.nimi;
rotu = _sobak.rotu;
vuosi = _sobak.vuosi;
return *this;
}
int main(void){
Sobak *x= new Sobak();
Sobak *y= new Sobak(" doggy ","stupid ","1980");
x->printMe();
y->printMe();
*x = *y;
x->printMe();
delete(y);
delete(x);
return 0;
}
(c) Zuber
Зуб, собаки стока не живут :)
А мне откуда знать. Я кошек люблю. :)
Prosto_tak
10-02-2006, 01:06
Спасибо! А я в правильном месте поделила на два файла?
Спасибо! А я в правильном месте поделила на два файла?
Да, думаю, да. Класс в один файл, имплементацию в другой. Только сейчас взглянул на код "задания". там, фроде, ентих операторов еше куча должна быть, типа ++ и << i +. >
Prosto_tak
10-02-2006, 01:22
Там еще написанно, что
добавить в класс Koira следующих нагрузку операций или операторов?(operaattoreiden kuormitus):
++ сделайте так:
a++; прибавляет к году родения "a" один год
++a;
+ сделайте так:
a + b; к имени А добавляем имя Б (посерединке пробел),
к породе А добовляем породу Б (посерединке пробел),
а год рождения не меняется
< сделайте так:
if (a < b) … если год рождения А меньше чем год рождения Б, функция фозвращает truen, в другом случае falsen
<< operaattori ?при помощи друга?? ystävän avulla
и дается код, который надо дополнять:
---
#include <iostream>
#include <string>
using namespace std;
#include "Koira.hpp"
// palauttaa arvonaan uuden Koira-olio, jonka tiedot
// on pyytanyt kayttajalta
Koira * luoKoira() ;
// palauttaa arvonaan paikallisen Koira-olion
// koiran tiedot viedaan parametreina nimi, rotu ja vuosi
Koira luoKoira(char *, char *, int);
int main()
{
Koira *p;
Koira koira;
cout <<"\nOletusmuodostin koira:\n " << koira;
p = luoKoira();
cout <<"\nluoKoira-metodin koira:\n" << *p;
Koira *q = new Koira (*p);
cout <<"\nKopiointimuodostin koira:\n" << *q;
koira = luoKoira
(" iitu "," paimensukuinen suomen lapinkoira ", 1988);
cout <<"\nluoKoira(char*, char*, int) -metodin koira:\n"<<koira;
Koira koira2;
koira2 = *p + *q;
cout <<"\n*p + *q koira: \n" << koira2;
Koira koira3;
koira3 = koira2++;
cout <<"\n"<<koira3 <<" != " << koira2;
koira3 = ++koira2;
cout <<"\n"<<koira3 <<" = " << koira2;
delete p;
delete q;
cout <<"\n\n**LOPPU***\n";
cin.ignore()
return 0;
}
---
Ну, енто, значит, дополнительное задание :). Я иду спать :) Оставляю тебе линк на примеры по оператор оверлоадинг.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_overloaded_operators.asp
А можешь БОЛДОМ выделить те места, где задается обрезание пробелов в словах?
string cutString(string daInput){
int counter = 0;
string ret = daInput;
counter = ret.find_first_not_of(" ");
ret.erase(0,counter);
counter = ret.find_last_of(" ");
ret.erase(counter);
return ret;
}
Усе, финал версион :)
#include <string>
#include <iostream>
using namespace std;
class Sobak{
private:
string nimi;
string rotu;
string vuosi;
public:
// konstructor
Sobak();
// kostruktor so znachenijami (esli nado)
Sobak(string /*name*/, string /*breed*/, string /*year*/);
// destruktor
~Sobak();
void setName(string name);
string getName(void);
void setBreed(string name);
string getBreed(void);
void setYear(string name);
string getYear(void);
Sobak &operator=( Sobak & );
// debug
void printMe(void);
private:
string cutString(string);
};
Sobak::Sobak(){
// nothing
nimi = "";
rotu = "";
vuosi = "";
}
Sobak::~Sobak(){
// nothing
}
Sobak::Sobak(string name, string breed, string year){
this->setName(name);
this->setBreed(breed);
this->setYear(year);
}
(c) Zuber
Здравствуйте.
Позволю себе слегка покритиковать Ваше решение - не ради принижения Ваших програмистских способностей, а только лишь ради нахождения лучшего решения.
Возможно, моё решение слегка и не вписывается в требуюмую функцинальность.
1. Собака рождается обычно известной породы => порода должна быть в конструкторе.
2. Порода собаки не может изменяться => SetBreed - позволяет это (вивисекция?)
3. Год рождения собаки тоже не может изменяться => должен передаваться конструктору. Единственная здесь устанавливомое поле - кличка собаки (может, всё таки имя:) - можно её сменить в зависимости от настроения хозяина когда годно.
Конструктор по умолчанию у Вас странный. Уж если он Вам так необходим - присваивайте значения в списке инициализации - это гораздо эффективнее. Та же беда с конструктором и другим...
Итак, на мой взгляд конструктор должен быть один, принимающий значения породы и года. Кличку хозяин даст позже. Конструктор же по умолчанию, если и нужен, то должен быть private, что означает его использование лишь инициализаторами С++, а не клиентами класса.
4. По правилам хорошего тона все get методы должны возвращать только константы. Хотя, в Вашем случае это не ссылки и не указатели - и так покатит (но подумайте о стиле, всё же)
5. Породу я бы сделал указателем на класс породы, а не её именем, потому как порода - это набор свойств, которые удачно инкапсулируются соответствующим классом, а не только название. Представьте что кому то захотелось узнать поподробнее про собачонку. Узнал породу, и что , лезем в интернет за инфой? А у нас бы тут уже и ссылочка имелась на всю инфу, все линки... - и не надо усложнять жизнь поиском, и памяти меньше потратим.
6. Деструктор всегда должен быть витруальным - опять таки по правилам хорошего тона - Вы породите подкласс Цирковой собаки, поведёте её на выставку Собак, и не сможете затем с этой Выставки уничтожить её Цирковые достоинства....
7. Вы действительно считаете, что Собака должна уметь резать строки? Мне кажется, Собака создавалась чтобы бегать, прыгать, размножаться, ногу поднимать... Резать строки должен РезательСтрок - совсем другой объект, класс если хотите, причём сейчас он это делает так, а завтра будет делать ещё эффективнее - и Собака ничего про это не должна знать. Резать он будет их не только Собаке, а ещё и Кошкам, Белкам, и Зайчикам. Выход - убрать нафик cutString из Собаки, а все значения на входе передавать инварианту - методу, который проверяет (validate) состояние объекта Собака, или параметов для Собаки, и если надо, то и правит их по своим правилам => может и подрезать строки, пользуясь переданной ему ссылкой на РезателяСтрок... Этот злобный валидатор Собак может быть совершенно другим классом, например другом (friend) Собак... Не скрещивайте Собак с бездушным РезателемСтрок:)
Вои моё мнение. хотите, принимайте - хотите нет. Может задание и ставит целью научить писать set/get, но писать грамотно нужно стараться всегда.
Не принимайте всерьёз мою критику, Зубер, я просто развлекаюсь:)
Удачи.
ИЦQ на Wиндах есть, но я сейчес везде линух гоняю. Слишком много вирусов стало кругом
Так в линуксе же тоже аська есть, причем порой даже встроенная :)
Единственная здесь устанавливомое поле - кличка собаки (может, всё таки имя:)
Позволю себе покритиковать Вас - вы плохо учили русский язык в школе - у животных КЛИЧКА, а никак не имя :)
Позволю себе покритиковать Вас - вы плохо учили русский язык в школе - у животных КЛИЧКА, а никак не имя :)
Жалко, что интернет не передаёт интонации.... тогда бы Вы услышали иронию в том сообщении. Хотя, перечитав его снова и снова, Вы всё же поймёте, что я именно это и сказал.
Здравствуйте.
Конструктор по умолчанию у Вас странный. Уж если он Вам так необходим - присваивайте значения в списке инициализации - это гораздо эффективнее. Та же беда с конструктором и другим...
Итак, на мой взгляд конструктор должен быть один, принимающий значения породы и года. Кличку хозяин даст позже. Конструктор же по умолчанию, если и нужен, то должен быть привате, что означает его использование лишь инициализаторами С++, а не клиентами класса.
Ну, Ц++ у менаы на очень среднем уровне, т.к. я не часто его использую. Любая критика из велкам - больше буду знать. Один конструктор означает, что цлиент цласса не может создать обьект не передавая никаких параметров. ИМХО, может быть очень надоедливой фичей, если учесть, что там будет оператор "=".
4. По правилам хорошего тона все гет методы должны возвращать только константы. Хотя, в Вашем случае это не ссылки и не указатели - и так покатит (но подумайте о стиле, всё же)
Ну, вроде один простой (цаст) делает из цонста нецонст :).
5. Породу я бы сделал указателем на класс породы, а не её именем, потому как порода - это набор свойств, которые удачно инкапсулируются соответствующим классом, а не только название. Представьте что кому то захотелось узнать поподробнее про собачонку. Узнал породу, и что , лезем в интернет за инфой? А у нас бы тут уже и ссылочка имелась на всю инфу, все линки... - и не надо усложнять жизнь поиском, и памяти меньше потратим.
ну, там в задаче, вроде, стринга была :). А так, человеку еше один класс надо было бы писать.
6. Деструктор всегда должен быть витруальным - опять таки по правилам хорошего тона - Вы породите подкласс Цирковой собаки, поведёте её на выставку Собак, и не сможете затем с этой Выставки уничтожить её Цирковые достоинства....
Ну, елси мы породим другой калсс, то он будет иметь собственный деструктор который будет уничтожать цирковые качества и передавать управление деструктору супер-класса. Или я чего-то не понял?
7. Вы действительно считаете, что Собака должна уметь резать строки? Мне кажется, Собака создавалась чтобы бегать, прыгать, размножаться, ногу поднимать... Резать строки должен РезательСтрок - совсем другой объект, класс если хотите, причём сейчас он это делает так, а завтра будет делать ещё эффективнее - и Собака ничего про это не должна знать. Резать он будет их не только Собаке, а ещё и Кошкам, Белкам, и Зайчикам. Выход - убрать нафик цутСтринг из Собаки, а все значения на входе передавать инварианту - методу, который проверяет (валидате) состояние объекта Собака, или параметов для Собаки, и если надо, то и правит их по своим правилам => может и подрезать строки, пользуясь переданной ему ссылкой на РезателяСтрок... Этот злобный валидатор Собак может быть совершенно другим классом, например другом (фриенд) Собак... Не скрещивайте Собак с бездушным РезателемСтрок:)
Ну, здесь соглашусь, что резатель строк может быть другим классом. Хотя, валидаор на все свойства собаки не есть еффективно. Если, например, вы хотите изменить только имя, то зачем валидатору проверять вся остальное?
В данном случае, резатель строк просто обшая функциональность, которая должна присутствовать в двух сет методах. Может, по стилю, оно и не правильно, но количества кода для данной простой операции гораздо меньчше. ИМХО, сложность десигна должна соответствовать задаче. Если мы знаем, что дальше "Собака" дело не пойдет, то можно слегка прогнуть ООП правила. Плюс, человек не может разглядеть резатель даже в моем коде, а, представьте, френдов и виртуальные функции :)
:D
Ну, Ц++ у менаы на очень среднем уровне, т.к. я не часто его использую. Любая критика из велкам - больше буду знать. Один конструктор означает, что цлиент цласса не может создать обьект не передавая никаких параметров. ИМХО, может быть очень надоедливой фичей, если учесть, что там будет оператор "=".
Ну, вроде один простой (цаст) делает из цонста нецонст :).
ну, там в задаче, вроде, стринга была :). А так, человеку еше один класс надо было бы писать.
Ну, елси мы породим другой калсс, то он будет иметь собственный деструктор который будет уничтожать цирковые качества и передавать управление деструктору супер-класса. Или я чего-то не понял?
Ну, здесь соглашусь, что резатель строк может быть другим классом. Хотя, валидаор на все свойства собаки не есть еффективно. Если, например, вы хотите изменить только имя, то зачем валидатору проверять вся остальное?
В данном случае, резатель строк просто обшая функциональность, которая должна присутствовать в двух сет методах. Может, по стилю, оно и не правильно, но количества кода для данной простой операции гораздо меньчше. ИМХО, сложность десигна должна соответствовать задаче. Если мы знаем, что дальше "Собака" дело не пойдет, то можно слегка прогнуть ООП правила. Плюс, человек не может разглядеть резатель даже в моем коде, а, представьте, френдов и виртуальные функции :)
:D
Очень рад адекватному восприятию критики!
Отвечаю на Ваши комментарии:
1.cast из const не const делает или нет - меня совершенно не интересует, потому что я этим никогда не воспользуюсь. Если делает - это большая глупость. И если возникла в этом надобность - причина кроется в плохом дизайне. Исправьте дизайн, и не понадобится на лету превращать муху в слона, и говорить, что так оно и было:)
2. Порода в задаче стояла как string. Без комментариев. Если задача такая, то решение должно быть адекватно задаче. Не надо воротить супер пупер, если всё просто. Нет возражений у меня, убедили. Но, в качестве комментария к решению - это (моё предложение) бы покатило, и ещё как...
3. Вы похоже не полностью понимаете преимущества ООП, а именно самой мощной его парадигмы - полиморфизма. Деструктор должен быть виртуальным для того, чтобы уничтожить объект по ссылке на родительский класс. Вы произведёте на свет ЦирковуюСобаку, затем отправите её на Выставку, передав её туда ссылкой или указателем на Собаку, потому что Выставка будет учитывать именно Собак, а не создавать свой список для каждого подвида Собак. Затем, когда Выставка закроется, она "уничтожит" всех Собак, одним списком, вызывая деструкторы Собак, а не пытаясь разобраться что это за конкретный подвид, и затем вызывать в case деструктор именно для этого класса.
Перечитайте про полиморфизм и виртуальные функции.
4. валидатор-инвариант - это безопасный подход. Причём Валидатор может быть публичным - пусть и клиенты убедятся, что собака правильная, если им это нужно. И именно все поля, правильнее говоря и не поля, а состояние объекта, в общем случае оно не только поля, но и отношение этих полей друг к другу и к состоянию вызвавшего контекста. Вот реализация Валидатора будет сокрыта, и будет инкапсулировать все детали определения правильной собаки. Если же писать оптимальный код в ущерб безопасному - сами с опытом убедитесь что результат обратный получится. Если клиент будет убеждаться в правильности собаки сам, вы добавите/уберёте какие то свойства пса, и все - кранты, клиент падает, потому что валидейтит что то не в синхроне с вашей улучшенной собакой.
5. Резатель в Собаке - это неверно. Резатель - это утилита обработки строк, ну нафига козе баян? Может для такой учебной задачи и сойдёт, но согласитесь: как нас учат, так мы и делаем в будущем, на реальных проектах. Уж лучше сразу сложно, но правильно, ИМХО. Если лень писать класс, ну сделайте его хоть глобальным, но никак не пришивайте бедной Собаке...
Удачи.
Здравствуйте.
1. Собака рождается обычно известной породы => порода должна быть в конструкторе.
2. Порода собаки не может изменяться => SetBreed - позволяет это (вивисекция?)
3. Год рождения собаки тоже не может изменяться => должен передаваться конструктору. Единственная здесь устанавливомое поле - кличка собаки (может, всё таки имя:) - можно её сменить в зависимости от настроения хозяина когда годно.
Конструктор по умолчанию у Вас странный. Уж если он Вам так необходим - присваивайте значения в списке инициализации - это гораздо эффективнее. Та же беда с конструктором и другим...
Итак, на мой взгляд конструктор должен быть один, принимающий значения породы и года. Кличку хозяин даст позже. Конструктор же по умолчанию, если и нужен, то должен быть private, что означает его использование лишь инициализаторами С++, а не клиентами класса.
Удачи.
Еще перед решеним проблемы не плохо взлянуть в параметры, которым должна удовлетворять система, а именно
int main()
{
Koira *p;
Koira koira;
cout <<"\nOletusmuodostin koira:\n " << koira;
p = luoKoira();
cout <<"\nluoKoira-metodin koira:\n" << *p;
Koira *q = new Koira (*p);
cout <<"\nKopiointimuodostin koira:\n" << *q;
koira = luoKoira
(" iitu "," paimensukuinen suomen lapinkoira ", 1988);
cout <<"\nluoKoira(char*, char*, int) -metodin koira:\n"<<koira;
Koira koira2;
koira2 = *p + *q;
cout <<"\n*p + *q koira: \n" << koira2;
Koira koira3;
koira3 = koira2++;
cout <<"\n"<<koira3 <<" != " << koira2;
koira3 = ++koira2;
cout <<"\n"<<koira3 <<" = " << koira2;
delete p;
delete q;
cout <<"\n\n**LOPPU***\n";
cin.ignore()
return 0;
}
Учитывая что должно быть Koira koira;, To Zuber По сути прав, даже если по логике, иметь пуской конструктор глупо, исходя из человеческого понятия собака.
Но если мыслить абстактно, то можно предположить, что собака появляется беликим шариком на двух ножках, и уже процесс задания породы, именяет ее внешний облик, и можно предположить что собаку можно переделывать например 5 раз за ее жизнь.
С годом рождения тут конечно тяежеле. Но заказчик в тех. описании задал наличие
пустого конструктора.
Yanychar
10-02-2006, 13:36
Еще и по-фински :gy: не... нафик-нафик... я спать хочу =)
"Могу переводить с английского, немецкого, французского и итальянского, но не хочу!"
Очень рад адекватному восприятию критики!
:)
1.цаст из цонст не цонст делает или нет - меня совершенно не интересует, потому что я этим никогда не воспользуюсь. Если делает - это большая глупость. И если возникла в этом надобность - причина кроется в плохом дизайне. Исправьте дизайн, и не понадобится на лету превращать муху в слона, и говорить, что так оно и было:)
Здесь не соглашусь. "Константы" есть всего лишь стиль программирования, ограничиваюший возможные ошибки при использовании класса, но, в тоже время может повлечь за собой дополнительные проблемы с несоответствием типов,т.к. цонст инт и инт цомпилятор может рассматривать по разному и не делать автоматического каста.
3. Вы похоже не полностью понимаете преимущества ООП, а именно самой мощной его парадигмы - полиморфизма. Деструктор должен быть виртуальным для того, чтобы уничтожить объект по ссылке на родительский класс. Вы произведёте на свет ЦирковуюСобаку, затем отправите её на Выставку, передав её туда ссылкой или указателем на Собаку, потому что Выставка будет учитывать именно Собак, а не создавать свой список для каждого подвида Собак. Затем, когда Выставка закроется, она "уничтожит" всех Собак, одним списком, вызывая деструкторы Собак, а не пытаясь разобраться что это за конкретный подвид, и затем вызывать в цасе деструктор именно для этого класса.
Перечитайте про полиморфизм и виртуальные функции.
мне казалось, что коснтрукторы и деструкторы вызываются автоматически через неw() делете().
4. валидатор-инвариант - это безопасный подход. Причём Валидатор может быть публичным - пусть и клиенты убедятся, что собака правильная, если им это нужно. И именно все поля, правильнее говоря и не поля, а состояние объекта, в общем случае оно не только поля, но и отношение этих полей друг к другу и к состоянию вызвавшего контекста. Вот реализация Валидатора будет сокрыта, и будет инкапсулировать все детали определения правильной собаки. Если же писать оптимальный код в ущерб безопасному - сами с опытом убедитесь что результат обратный получится. Если клиент будет убеждаться в правильности собаки сам, вы добавите/уберёте какие то свойства пса, и все - кранты, клиент падает, потому что валидейтит что то не в синхроне с вашей улучшенной собакой.
Ну, все-равно, он не есть самый еффективный. Если надо собаке проверить правильность имени, а ее подвергают полному мед-осмотру на неделю - хозяева не будут довольны :lol:
5. Резатель в Собаке - это неверно. Резатель - это утилита обработки строк, ну нафига козе баян? Может для такой учебной задачи и сойдёт, но согласитесь: как нас учат, так мы и делаем в будущем, на реальных проектах. Уж лучше сразу сложно, но правильно, ИМХО. Если лень писать класс, ну сделайте его хоть глобальным, но никак не пришивайте бедной Собаке...
Нее... ну глобальная функция - енто так же неправильно, как собаке пришивать.
:)
Здесь не соглашусь. "Константы" есть всего лишь стиль программирования, ограничиваюший возможные ошибки при использовании класса, но, в тоже время может повлечь за собой дополнительные проблемы с несоответствием типов,т.к. цонст инт и инт цомпилятор может рассматривать по разному и не делать автоматического каста.
мне казалось, что коснтрукторы и деструкторы вызываются автоматически через неw() делете().
Ну, все-равно, он не есть самый еффективный. Если надо собаке проверить правильность имени, а ее подвергают полному мед-осмотру на неделю - хозяева не будут довольны :lol:
Нее... ну глобальная функция - енто так же неправильно, как собаке пришивать.
Константы отнюдь не стиль программирования. Это глубокое и опасное заблуждение. Константы - это часть дизайна, накладывающая ограничения на способы использования объектов. и очень важных, замечу, ограничений. Возвращая неконстантную ссылку на свойство - вы отдаёте часть объекта в неподконтрольное использование - что чревато полным крахом. Кастинг - это зло. Меняйте ваше представление о константах, и Ваша жизнь значительно облегчится.
Конструкторы и деструкторы. Вам должно быть наплевать когда они вызываются. мыслите абстрактно от контекстов и реализаций. Усвойте - конструктор вызывается в момент создания объекта. Кто, где, когда, как, через new, по умолчанию, или ещё как то, создаёт объект - вам по барабану. CType Object; тоже вызовет конструктор - но тут никакого new нет...
Деструктор вызывается в момент уничтожения объекта, а не вызовом delete. Привести примеры? Выход объекта из области видимости, вызов деструктора явно, через delete, наконец. Наверняка ещё есть способы, или будут. Не заморачивайтесь с контекстом, делайте только то, что требуется. Дело деструктора - освободить ресурсы, занятые объектом, и точка.
Насчёт полиморфизма, не уверен, поняли или нет. Вы создаёте объект нужного класса, а обращаетесь с ним, и однотипными, по ссылке на их родительский класс, и уничтожить можете также по той же ссылке. Если деструктор не виртуальный, уничтожиться только родительская часть объекта, деструктор самогО класса не вызовется.
Уверяю Вас, безопасность и эффективность суть вещи несравнимые, потому как безопасность (ака надёжность, ака стоимость сопровождения) на порядки нужнее и важнее эффективности. Это ИМХО, взятое из 20-летнего опыта программирования. Спорить не буду, если есть другие мнения.
Да, глобальная функция плохо, я её Вам и не предлагал, а вот статическая, в каком нибудь StringUtils классе - самое то. То же что и глобальная, только скрыта именем класса. Именно это я имел ввиду, говоря про "глобальный класс".
Удачи.
Еще перед решеним проблемы не плохо взлянуть в параметры, которым должна удовлетворять система, а именно
Учитывая что должно быть Koira koira;, To Zuber По сути прав, даже если по логике, иметь пуской конструктор глупо, исходя из человеческого понятия собака.
Но если мыслить абстактно, то можно предположить, что собака появляется беликим шариком на двух ножках, и уже процесс задания породы, именяет ее внешний облик, и можно предположить что собаку можно переделывать например 5 раз за ее жизнь.
С годом рождения тут конечно тяежеле. Но заказчик в тех. описании задал наличие
пустого конструктора.
Соглашусь с Вами, я был не прав, не взглянув на требования, решая эту задачу.
Опять же из моего опыта - чем меньше знаешь о продукте, который проектируешь - тем лучше получаешь результат. Это где-то опровергает фундаментальную мысль о том, что перед реализацией нужно всё тщательно изучить, просчитать, взвесить и учесть по максимуму. Это ложь, которой нас учат уже много лет.
Не зная ничего, проектируешь абстрактно, пользуясь только здравым смыслом и опытом. Получается вещь, пригодная для любого применения.
Зная всё, или почти все о назначении продукта, пытаешься учесть все варианты использования, и получается каша из ошибок и недочётов.
Софт - это живой продукт, подлежащий изменению так часто, как требуется. Учитывать в проекте детали будущего использования - непростительная и дорогая ошибка.
Мощное продумывание же должно касаться не подгонки под варианты использования, а возможности обобщения, абстракции, и применении шаблонов готовых решений проектирования, чтобы учесть будущее расширение и адоптацию. Ну о шаблонно-ориентированном программировании я уже где-то тут писАл.
Удачи.
Развели, понимаешь, липаевщину :)
Много-много текста и ни одной строчки кода :)
Еще перед решеним проблемы не плохо взлянуть в параметры, которым должна удовлетворять система, а именно ...
Учитывая что должно быть Koira koira;, To Zuber По сути прав...
С годом рождения тут конечно тяежеле. Но заказчик в тех. описании задал наличие
пустого конструктора.
Есть решение и для этого варианта - конструктор с параметрами по умолчанию. Тот же самый, что я предлагал, с параметрами Порода, и ГодРождения, только по умолчанию принимающими что то. Тогда возможно и такое порождение: Koira koira;
Это решение не пришло мне в голову сразу, потому что я сам никогда так не делаю; аргументы по умолчанию - очень спорный подход, чреватый ошибками, и трудно сопровождаемый. Не рекомендую его использовать.
ИЦQ на Wиндах есть, но я сейчес везде линух гоняю. Слишком много вирусов стало кругом
А почто под линь аську не поставишь? Хорошо же бегает
Развели, понимаешь, липаевщину :)
Много-много текста и ни одной строчки кода :)
ну и что?
алварец, между прочим, дело говорит :respect:
главное понять, а уж код набить - дело 5-ти минут
У меня например - работа над багом -> 2 дня -> 2 строчки -> красиво :)
Работа на совесть ;)
Опять мне надо домашку сделать, но я чет вааще ниче не понимаю, есть тут знатоки C++, которые могли бы помочь? :shuffle:
Я так думаю, знатоки найдутся и напишут такое от чего у Вашего препода возникнут сомнения в смысле преподской жизни...
Но смысл был немножко в другом...
Вы бы написали, то что Вы думали... и попросили бы покритиковать
а потом бы переписали бы, всё, гениально, и было бы Вам щастье...
:zaika:
Да, вполне возможно, что препод перегреется :)
IMHO, использовать в программе для именования переменных любой язык, отличный от английского - дурной стиль. Я в таких случаях всегда вспоминаю, как в одной конторе в России, в которой использовали копмилятор Algol-86, допускающий кириллицу, один из моих коллег с Востока стал называть переменные по-монгольски. =)
ну и что?
алварец, между прочим, дело говорит :respect:
Конечно дело говорит. :respect: -ище.
Просто этот стиль изложения липаевщиной и называют.
К Липаеву у меня тоже :respect: огромный.
[russian.fi, 2002-2014]