IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> STL, Итераторы C++
сообщение
Сообщение #1


Ночной волк
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской

Репутация: -  1  +


Работа с библиотекой STL. Требуется создать вектор указателей на объекты типа алкогольные напитки. Программа должна уметь добавлять новый элемент, удалять элемент, сортировать по убыванию названия, находить первое включение указанного напитка.
1. В чем ошибки? Нерабочие участки программы закомментированы.
2. Как реализовать по убыванию с помощью итератора? Что за итератор возвращает обратное значение
3. Как присвоить значение итератору? У меня что то = не работает.
 #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#define n 5
using namespace std;
///////////////////////////////////////
class liquido{
protected:
string name;
double ro;
public:
liquido(){
name="acqua";
ro=0;
}

liquido(string str){
name=str;
ro=0;
}

liquido(string str, double p){
name=str;
ro=p;
}


void print(){
cout << "Liquido " << name << endl;;
cout << "R\'o " << ro << endl;;
}

void set_ro(double p){
ro=p;
}

void set_name(string str){
name=str;
}



};
/////////////////////////////////////////////
class alcohol:public liquido{
float carico;
public:
alcohol(){
name="acqua";
ro=0;
carico=0;
}

alcohol(string str){
name=str;
ro=0;
}

alcohol(string str, double p){
name=str;
ro=p;
carico=0;
}

alcohol(string str, double p, float c){
name=str;
ro=p;
carico=c;
}
void set_c(float c){
carico=c;
}

void print(){
cout << "\nLiquido " << name << endl;;
cout << "R\'o " << ro << "; Carico " << carico << endl;
}

friend bool operator==(const alcohol& a1, const alcohol& a2){
return (a1.name==a2.name);
}

friend bool operator<(const alcohol& a1, const alcohol& a2){
return (a1.name<a2.name);
}




};
//////////////////////////////////////////////
////Function objects//////////////////////////
//////////////////////////////////////////////
class compareAlcohol{
public:
bool operator()(const alcohol* a1, alcohol* a2){
return *a1<*a2;
}
};
//////////////////////////////////////////////
//class printAlcohol{
//public:
// void operator() (const alcohol* a){
// *a->print();
// }
//};
/////////////////////////////////////////////
/////////MAIN////////////////////////////////
/////////////////////////////////////////////


int main(){
alcohol Martini("Martini Bianco 1863", 986.5, 18.5f);
alcohol Martini2("Martini Bianco 1863", 986.5, 18.5f);
Martini.print();
Martini.set_c(19.5f);
Martini.set_ro(987.);
Martini.print();
////////////////////////////////
alcohol* temp;
string gen;
vector<alcohol*> MyVector;
vector<alcohol*>::iterator MyIterator;
for (int i=0; i<n; i++){
gen= "Alcohol"+i;
cout << gen << endl;
temp = new alcohol(gen, i+10, i);
MyVector.push_back(temp);
}
cout << MyVector.size()<<endl;
// for_each(MyVector.begin(), MyVector.end(), printAlcohol);//output
// sort(MyVector.begin(), MyVector.end(), compareAlcohol);

/////////////////
///////////////
//////////ADD ELEMENT///////////
////////////////////////////////

temp = new alcohol("NEW ALCOHOL", 893.7, 39.4f);
// MyIterator=3;
// MyVector.insert(temp,MyIterator);
// for_each(MyVector.begin(), MyVector.end(), printAlcohol);//output

////////////////////////////////
////////DELETE ELEMENT//////////
////////////////////////////////
cout << "Which element delete?";
cin >> i;
delete MyVector[i];
// MyIterator = i;
// MyVector.erase(MyIterator,MyIterator);
// for_each(MyVector.begin(), MyVector.end(), printAlcohol);//output
////FIND ELEMENT/////
string sname;
cout << "Put Name for search";
cin >> sname;
// MyIterator=find(MyVector.begin(), MyVector.end(), sname);
// cout << MyIterator;



////////////CLEAR///////////////////////////////
while (!MyVector.empty()){
delete MyVector.back();
MyVector.pop_back();
}
return 0;
}



--------------------
Не думай о белой обезьяне.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Цитата
1. В чем ошибки? Нерабочие участки программы закомментированы.
А у тебя ошибки начинаются еще ДО того, как что-то закомментировано... Ну, например, ты в конструкторе класса alcohol зачем-то присваиваешь значения унаследованным полям сам, хотя для этого есть конструктор предка... Кстати, конструктор предка ты должен вызывать в конструкторе потомка, ты этого не делаешь... + к этому, есть такое понятие, как значения по умолчанию, то есть, вместо трех перегрузок конструктора liquido, достаточно:

class liquido {
liquido(string s = "acqua", double d = 0.0) {
name = s; ro = d;
}

// ...

class alcohol: public liquido {
alcohol(string s = "acqua", double d = 0.0, float f = 0.0): liquido(s, d) {
carico = f;
}
// ...
, это перекрывает все возможные комбинации, которые ты реализовывал вручную.

2) Инициализация:
Цитата
	for (int i=0; i<n; i++){
gen= "Alcohol"+i;
cout << gen << endl;
temp = new alcohol(gen, i+10, i);
MyVector.push_back(temp);
}
делает совсем не то, что ты подразумевал. В частности, "Alcohol" + 1 = "lcohol", а +2 = "cohol", ты сложением просто задаешь смещение от начала строки... Ты же хотел добавлять цифру в конец? Ну, так добавляй:
	char gen[20] = {0};
for (int i=0; i<n; i++){
sprintf(gen, "Alcohol%d", i);
cout << gen << endl;
temp = new alcohol(gen, i+10, i);
MyVector.push_back(temp);
}

3) Попытка печати вектора: ошибка, потому что printAlcohol должен быть не классом, а функцией:
void print_alcohol(alcohol *a) {
a->print();
}
// ...
for_each(MyVector.begin(), MyVector.end(), print_alcohol);
, а вот дальше, при попытке отсортировать вектор, ты делаешь обратную ошибку... У тебя есть класс, в котором который ввел предикат сравнения, но передавать-то тебе в std::sort надо не класс, а сам предикат:
sort(MyVector.begin(), MyVector.end(), compareAlcohol()); // вот так - правильно 


4) Добавление элемента в вектор:
	temp = new alcohol("NEW ALCOHOL", 893.7, 39.4f);
MyIterator=MyVector.begin() + 3; // Все очень просто, не число, а смещение от начала
MyVector.insert(MyIterator, temp); // сначала - итератор, потом - элемент


5) Удаление элемента... Я бы сделал это вот так:
	cout << "Which element delete?";
cin >> i;
delete (temp = MyVector[i]);
MyVector.erase(MyVector.begin() + i);


По-моему ничего не забыл...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Ночной волк
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской

Репутация: -  1  +


Спасибо огрмное Volvo. Все исправил.
Только не выходит Find

MyIterator = find(MyVector.begin(), MyVector.end(), Martini);


Этот код должен найти в векторе элемент равный Мартини, только не работает. И еще, можно использовать find, чтобы найти по параметру объекта, не используя лишние объекты. т.е.


MyIterator = find(MyVector.begin(), MyVector.end(), Martini.carico);

или просто

MyIterator = find(MyVector.begin(), MyVector.end(), "Alcohol2");


Два учебника уже прочитал, нигде нет подробного описания этой функции.


--------------------
Не думай о белой обезьяне.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Цитата
И еще, можно использовать find, чтобы найти по параметру объекта, не используя лишние объекты
Используй find_if:

// пишешь свой функтор
struct finder : std::binary_function<alcohol*, string, bool>
{
bool operator()(alcohol* const& in, string id) const
{
return (id == in->get_name());
}
};

// и запускаешь поиск:
MyIterator = find_if(MyVector.begin(), MyVector.end(), bind2nd(finder(), "Alcohol3"));
(*MyIterator)->print();
, но для того, чтобы это работало, придется в классе liquido сделать геттер get_name(), иначе к полю name нет доступа, оно защищенное, а не общее...

Цитата
Два учебника уже прочитал, нигде нет подробного описания этой функции.
Какие учебники ты читал?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Ночной волк
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской

Репутация: -  1  +


Т.Павловская, методичку свою, еще какие-то документы без названия..
Можешь что-нибудь посоветовать по STL? У меня очень дорогой hsdpa интернет, я не могу позволить себе скачивать все подряд, а потом разбираться.

Кстати я не понял вот это

finder : std::binary_function<alcohol*, string, bool>
и это
bind2nd



--------------------
Не думай о белой обезьяне.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Цитата
finder : std::binary_function<alcohol*, string, bool>
Хм... Ну, смотри... Создаем свой функтор - наследник от класса std::binary_function, то есть, функтор (так же как делает это binary_function) будет принимать 2 аргумента: первый - типа alcohol*, второй - типа string... А возвращать функтор будет значение типа bool (именно в таком порядке конкретизируется binary_function<>: тип первого параметра, тип второго параметра, и тип результата, обрати внимание).

А теперь - суть этого метода: при проходе по вектору КАЖДЫЙ его элемент передается в созданный функтор, и там сравнивается с заданной строкой... Причем, поскольку использована bind2nd, то доп. аргумент(строка в нашем случае) передается вторым параметром, а итератор - первым. Если надо, чтобы сначала передавался доп. аргумент, а потом - итератор, то используется bind1st... Ну, к примеру, можно было бы переписать функтор с другим порядком аргументов:
struct id_finder : std::binary_function<string, alcohol*, bool>
{
bool operator()(string id, alcohol* const& in) const
{
return (id == in->get_name());
}
};

, и вызвать
MyIterator = find_if(MyVector.begin(), MyVector.end(), bind1st(finder(), "Alcohol3"));
, тоже было бы корректно...

Цитата
Можешь что-нибудь посоветовать по STL?
Я пользуюсь книгой Николай Джосьютис, С++ Стандартная библиотека для профессионалов, ISBN: 5-94723-635-4 (английский вариант: "The C++ Standard Library: A Tutorial and Reference" Nicolai M. Josuttis, ISBN: 0-201-37926-0) и Scott Meyers: Effective STL
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 20.04.2024 17:33
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name