Не сте регистриран! Регистрирайте се БЕЗПЛАТНО, за да използвате услугите на сайта!

 Прост клас , броене на обектите и др.
Автор  jan (04.01.2005 15:46) съобщение до автора
Погледнат  1770 пъти добави към любими
Оценка добави коментар
Гласове  2 изпрати на приятел
Коментари  (6) абонирай се за C-Cplusplus
     
jan
     
 

////////////////////////////////////////////////////////////
//
//В програмата се дефинира клас с информация за студенти - успех и име.
//Демонстрира се броене на създадените обекти на класа, а също
//и поле (pos) съдържащо поредния номер на създаване на обекта.
//Обектите се разполагат в масив st. Демонстрира се и работата на
//функция (minStName) с масив, която намира минималното име(по азбучен
//ред). Заслужава си да се отбележи лекотата при работа с масиви.
//
////////////////////////////////////////////////////////////

#include <iostream.h>
#include <string.h>

using namespace std;

//Клас определящ полето за един студент
class student
{
//private променливи на класа
// Успех
    int rating;
// Име   
    string name;
    static int inst;
//Позиция на въвеждане   
    int pos;
public:
//Подразбиращ се конструктор
    student();
// Извежда стойността на полето rating  
    int outRat();
// Въвежда стойността на полето rating  
    void inputRat(int);
// Извежда стойността на полето name   
    string outName();
// Въвежда стойността на полето name   
    void inputName(string);
    int outPos();
};

int student::inst=0;

student::student()
{
    rating=0;
    name="";
    inst++;
    pos=inst;
};

int student::outPos()
{
    return pos;
};

int student::outRat()
{
    return rating;
};

void student::inputRat(int i)
{
    rating=i;
}

string student::outName()
{
    return name;
};

void student::inputName(string s)
{
    name=s;
};   

//връща обект с минимално (по азбучен ред) име
student minStName(student st[],int len)
{
    student temp;
    temp=st[0];
    for(int i=0;i<len;i++)
    {
        if(temp.outName()>st[i].outName())
        {
             temp=st[i];
        };
    };
    return temp;
};

int main()
{
// Информацията за колко студенти ще въвеждаме
    int numb,rating;
    string name;
    cout<<"Input number of studentsn";
    cin>>numb;
    student st[numb];
    //Въвеждане на данните
    for(int i=0;i<numb;i++)
    {
        cout<<"Input ratingn";
        cin>>rating;
        st[i].inputRat(rating);
        cout<<"Input namen";
        cin>>name;
        st[i].inputName(name);
    };
//Извеждане на обекта съдържащ информация за студента с
//минимално (по азбучен ред) име.
    cout<<"n"<<minStName(st,numb).outName()<<"    "<<minStName(st,numb).outPos()<<"n";
    return 0;
}



Ключови думи: c c++ c# програма клас броене обект




 1 посетител чете този скрипт (0 потребители и 1 гост)  
Активни потребители: ---
   
  

Еmail  
 

Здравей, Жан. Искам да кажа само едно, но много държа да го кажа. Това, което си написал и доста добро като идея, а мен това ме интересува, а не това че си сложил една ";" в повече, и аз изкрено те поздравявам. В случая забележките би трябвало да бъдат отправени по темата, и да не ни пука за точките и запетаите, тук важна е идеята. Точно поради това мразя БГ форумите. Има доста добри програмисти, които страшно много издребняват.
Благодаря.

  dido2k на 12.01.2005 20:55

И още няколко неща, които биха направили програмата по-лесно четима и по-качествена :

1. Добре е да спазваш общоприетата конвенция за имена на методи, които служат за даване и извличане стойността на поле. А именно getField, setField (където Field е името на полето разбира се).

2. Всички методи, които само взимат стойност, е редно да се направят const методи. Т.е. метода за извличане на ratio-то е добре да е :
public int getRatio() const;
Така указваш на ползващите твоя клас, че този метод няма да промени обекта, за който се вика. И също така че може да се вика върху обекти не само от тип student, но и от тип const student. Все пак върху const обекти могат да се викат само const методи. Редно е за студент, чиито данни не можеш да променяш, да можеш да научиш вече въведените, не мислиш ли?

3. При търсенето на минимален елемент, ти вече си сложил във временната променлива нулевия. Тогава сравненията (т.е. цикъла for) трябва да почнат от елемент 1, а не от 0 - иначе първия път сравняваш нулевия елемент със самия него, което е напълно излишно.

4. Изобщо не слагай ";" след "}" -
{ };
е еквивалентно на :
{}
;
където последният ред е празен оператор. Излишно е.

5. В реда:         cout<<"n"<<minStName(st,numb).outName()<<"    "<<minStName(st,numb).outPos()<<"n";
викаш два пъти функцията minStName() и тя два пъти изчислява абсолютно едно и също. Правилното е да я викнеш веднъж, като съхраниш стойността във временна променлива.
Т.е. :
   student stud = minStName(st,numb);
   cout << "\n" << stud.outName() << "    " << stud.outPos() << "\n";

6. Когато предаваш на функция параметри, които са обекти, е добре да избягваш да ги предаваш като копие (както си направил при inputName(string)). Предавай по референция. И ако все пак искаш оригинала да не се променя, нека референцията е const.
Пример:
void setName(const string & name);

  Izida на 05.01.2005 13:46

Здравей Izida!

Връзките, които ми прати са много полезни.
От тук може да излезе добра статия:-)
ОК. Съгласен съм по принцип с това, което казваш, обаче има най-малко две причини за използването на конструктори без параметри:
1. Когато са ни необходими временни обекти (а това се случва доста често), какъв е смисълът временният обект да използва някакви реални данни, или ако не са реални то какви?
2. Когато се създава масив (или друга структура от обекти)
student *st=new student[7];
конструктора на класа ще се стартира 7 пъти, а това не винаги е удобно.

Освен това тъй като не можем да сме сигурни какво въвежда потребителя (например оценката може да е от 0 до 20) е необходимо да правим проверки, а да се прави такава проверка при всяко създаване на обект може да се окаже доста неикономично:-)

С поздрав jan

  jan на 05.01.2005 12:24

Здравей отново, Jan!

Тогава, когато са писани хедърите от типа <хедър.h>, още не са били въведени в езика именните пространства! За това и по-нататък са направени нови хедъри от типа <хедър> - в които вече ще намериш дефиницията на std. G++ компилира това по изключение. По стандарт трябва да включваш само НОВИЯ тип хедъри - тези без ".h". Иначе програмата ти ще си остане компилируема само под G++.

Освен това аз не ти говоря в конструктура по подразбиране (т.е. този без параметри) да не инициализираш член-променливите. Говоря ти да НЕ ПРЕДОСТАВЯШ конструктор по подразбиране, а само конструктор, който приема поне име! Така няма да има нужда да проверяваш обектите дали са валидни (т.е. дали името им е различно от ""), защото знаеш, че при създаването на всеки един обект създателя е посочвал име. Спестяваш си много проблеми като забраниш конструктора по подразбиране.

Пробвах с G++ - компилира се. Но се компилира единствено понеже G++ има разширения, които не са по стандарт. А една програма трябва да се пише така, че да се компилира на всеки стандартен компилатор. Ако искаш да видиш, пробвай да компилираш с опция на G++ "-pedantic" - ще видиш, че ако трябва да е по стандарт, то ще има грешка. Виж следното :
http://manju.cs.berkeley.edu/cil/cil011.html
http://www.ugrad.physics.mcgill.ca/reference/Gcc/gcc_4.html - точка 4.14
Както се вижда G++ поддържа т.нар. масиви с променлива дължина. Обаче по стандарт размера а масив в С++ трябва да е константен израз. Иначе масивът трябва да се задели динамично. Пак казвам - vector е най-добрият вариант в случая - нали е именно динамичен масив.

Препоръчвам ти да пробваш следния он-лайн компилатор -
http://www.comeaucomputing.com/tryitout/
Това е най-близкия до С++ стандарта компилатор, който знам за момента (ако знаеш по-близък - сподели). А важното една програма да е по стандарт е именно за да няма случки като тази - при мен да не се компилира. Comeau дори дава грешка, за дето си сложил ";" на края на дефинициите на функциите. Не забравяй : дефиницията на функцията е приключила със затварящата скоба, няма нужда от точка и запетая.

  Izida на 05.01.2005 10:49

Здрасти Izida!

Благодаря ти за коментара!
Ще се постарая да ти отговоря.
Съжалявам, но програмата се компилира:-)
Грешката ми е, че не съм споменал компилатора, а именно g++. Странно нали?
Но тази възможност

    int numb,rating;
.............................
    cin>>numb;
    student st[numb];
е напълно допустима.
Ще го компиллирам под MS! Всъщност вече се опитах, но грешката не беше тази.
Няма грешка да се използва именовано пространство и стар стил задаване на хедъри.
В конструктора се прави точно това. Инициализират се всички променливи на класа. Те трябва да се инициализират (просто е препоръчително). Да, няма студент без име. А какво ще стане ако се създаде обект с неинициализирано поле и след това полето се използва! По-скоро има студент без име, отколкото студент с това, което ще се намира в името му ако не се инициализира:-)
Една от първите задачи при писане на програми е инициализирането на дефинираните променливи!!!!!!!!!

Съжалям, че не съм създал завършено приложение или изрично не съм уточнил, какво още би било добре да се направи. А например:
1. Валидиране на име, успех въвеждан брой.
2. Поне още един конструктор.

Ако трябва да се продължава още доста дълго ще трябва да се пише.
Бих се радвал на още коментари и забележки.

  jan на 05.01.2005 07:40

1. Програмата е НЕКОМПИЛИРУЕМА!
    - Използван е хедъра <iostream.h> вместо по-новия <iostream> и въпреки това е направен опит да се използва пространството std (което не е декларирано в стария хедър, а единствено в новия!)
    - student st[numb]; е невалидна дефиниция, понеже стойността на numb не е известна по време на компилация, когато трябва да се задели място за масива. Т.е. не може да се използва за указване размера на масив.
   
2. Не е добра идея да разрешиш създаването на обекти student, попълнени с данни по подразбиране. В крайна сметка има ли в природата такова нещо като студент без име? Не забравяй, че твоята програма моделира и отразява реалния свят. Така че е по-добре да направиш само конструктор, който приема име - за да си сигурен, че всички обекти са инициализирани.

3. Използвай т.нар. динамичен масив vector. Така ще можеш да създаваш нови обекти student (като чрез описания в горната точка контруктор в момента на създаване им даваш и име) и да ги добавяш в масива. Обхождането си остава все така лесно и приятно.

  Izida на 04.01.2005 16:40

 

 
  • Интересно от Софтуер
 
  • Интересно от myLINKS
 
 
 
 



IT-PLACE.NET © 2004 - 2008