![]() |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
![]() |
ammaximus |
![]()
Сообщение
#1
|
![]() Ночной волк ![]() ![]() Группа: Пользователи Сообщений: 103 Пол: Мужской Репутация: ![]() ![]() ![]() |
Работа с библиотекой 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;
}
-------------------- Не думай о белой обезьяне.
|
![]() ![]() |
volvo |
![]()
Сообщение
#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);
}
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);
По-моему ничего не забыл... |
ammaximus |
![]()
Сообщение
#3
|
![]() Ночной волк ![]() ![]() Группа: Пользователи Сообщений: 103 Пол: Мужской Репутация: ![]() ![]() ![]() |
Спасибо огрмное 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");
Два учебника уже прочитал, нигде нет подробного описания этой функции. -------------------- Не думай о белой обезьяне.
|
volvo |
![]()
Сообщение
#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 нет доступа, оно защищенное, а не общее...Цитата Два учебника уже прочитал, нигде нет подробного описания этой функции. Какие учебники ты читал? |
ammaximus |
![]()
Сообщение
#5
|
![]() Ночной волк ![]() ![]() Группа: Пользователи Сообщений: 103 Пол: Мужской Репутация: ![]() ![]() ![]() |
Т.Павловская, методичку свою, еще какие-то документы без названия..
Можешь что-нибудь посоветовать по STL? У меня очень дорогой hsdpa интернет, я не могу позволить себе скачивать все подряд, а потом разбираться. Кстати я не понял вот это finder : std::binary_function<alcohol*, string, bool>
и это
bind2nd
-------------------- Не думай о белой обезьяне.
|
volvo |
![]()
Сообщение
#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 |
![]() ![]() |
![]() |
Текстовая версия | 29.07.2025 16:49 |