Чтение из файла записи в функции-члены класса и печать на консоли в C ++? - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть 2 класса, я делаю объект из второго класса (я передаю имя файла в качестве аргумента).Он должен распечатать содержимое файла, который содержит следующие данные в следующем формате:

A.Yordanov 1234567819
S.Todorov 3456789120
D.Lazarov 2569789054
P.Pavlov 4329549823
M.Kalinova 2367892343
B.Georgiev 659045324

Я перегружен оператор <<, но я, когда я пытаюсь cout << cty2, ничего не появляется на консоли дажехотя я положил файл в тот же каталог?

// OOP_Homework.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <fstream>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
fstream f;
class CPerson {
    string name;
    string egn;
public:
    CPerson(string n, string e) {
        name = n;
        egn = e;
    }
    friend bool operator<(CPerson p1, CPerson p2) {
        if (p1.egn < p2.egn) {
            return true;
        }
        return false;
    }
    friend bool operator==(CPerson p1, CPerson p2) {
        if (p1.egn == p2.egn) {
            return true;
        }
        return false;
    }
    friend ostream& operator<< (ostream o, CPerson pn) {
        o << "Egn" << endl;
        o << pn.egn << endl;
        o << "Name:" << endl;
        o << pn.name << endl;
    }
    friend istream& operator>> (istream is, CPerson p) {
        is >> p.egn;
        is >> p.name;
        return is;
    }
    string getName() {
        return name;
    }
    string getEgn() {
        return egn;
    }
    void setName(string n) {
        name = n;
    }
    void setEgn(string e) {
        egn = e;
    }
};
class CCity {
    vector<CPerson> pr;
public:
    CCity(string fl) {
        f.open(fl, ios::out);
        string name = "", fn = "";
        while (!f.eof()) {
            //формата на данните във файла е във вида:
            //<име на студент> <факултетен номер>
            cin >> name >> fn;
            pr.push_back(CPerson(name, fn));
        }
        f.close();
    }
    //помощен getter за вектора  pr;
    vector<CPerson> getV() {
        return pr;
    }
    friend ostream& operator<<(ostream& os, CCity& psn) {
        vector<CPerson> ps = psn.getV();
        for (auto x = ps.begin(); x != ps.end(); x++) {
            os << x->getName() << endl;
            os << x->getEgn() << endl;
        }
        return os;
    }
    vector<CPerson> getDuplicate() {
        set<CPerson> temp;
        vector<CPerson> duplicates;
        for (auto i = pr.begin(); i != pr.end(); i++) {
            for (auto x : pr) {
                if (*i == x) {
                    temp.insert(*i);
                }
            }
        }
        for (auto j : temp) {
            duplicates.push_back(j);
        }
        temp.clear();
        //връщаме студентите с повтарящи се егн-та
        return duplicates;
    }
    void removeDuplicates() {
        sort(pr.begin(),pr.end());
        pr.erase(unique(pr.begin(), pr.end()));
    }
    void removeVector(vector<CPerson> ob) {
        for (auto i:ob) {
            for (auto x = pr.begin(); x != pr.end(); x++) {
                if (i == *x) {
                    pr.erase(x);
                }
            }
        }
    }
};
int main()
{
    CCity  cty2("persons.txt");
    //cout << cty1 << endl;
    cout << cty2 << endl;
    return 0;
}

1 Ответ

0 голосов
/ 04 декабря 2018

Код вашей перегрузки для operator<< должен быть

friend ostream& operator<< (ostream &o, const CPerson &pn) {
    //                              ^   ^^^^^         ^

    o << "Egn" << endl;
    o << pn.egn << endl;
    o << "Name:" << endl;
    o << pn.name << endl;

    return o;  // since return type is ostream&
}

Вы должны передавать поток по ссылке и возвращать его, как только вы закончили его использовать.Передача по ссылке гарантирует, что используется тот же поток (в отличие от передачи по значению).

Еще один момент, на который следует обратить внимание, это аргументы функции CPerson p.Они также должны быть переданы по ссылке.С operator<< ваш CPerson не будет изменен, поэтому мы можем сохранить его как const.

Вы также можете следить за своим operator>>.Опять же, istream is должно быть istream &is.С параметром CPerson p вы будете изменять его, так что вы определенно захотите передать его в качестве ссылки.

friend istream& operator>> (istream &is, CPerson &p) {
    //                              ^            ^

    is >> p.egn;
    is >> p.name;
    return is;
}

В других ваших перегрузках вы должны использоватьconst CPerson &p также.Более того, ваши перегрузки для operator< и operator== не обязательно должны быть friend ed, поскольку они не имеют доступа к закрытым членам других классов.Таким образом,

bool operator<(const CPerson &p1, const CPerson &p2) {
    if (p1.egn < p2.egn) {
        return true;
    }
    return false;
}

bool operator==(const CPerson &p1, const CPerson &p2) {
    if (p1.egn == p2.egn) {
        return true;
    }
    return false;
}

Вы захотите привыкнуть к передаче ваших классов по ссылке, так как это экономит место (не нужно копировать-конструировать другой экземпляр класса, как при передаче по значению).Таким образом, эффективнее как в пространстве, так и в плане производительности передавать свои классы по ссылке.

...