C ++ эквивалент C # ООП, если (Мальчик b студент) - PullRequest
0 голосов
/ 28 октября 2018

Я пытаюсь реализовать систему выше с использованием C ++.Ранее я использовал C # и OOP для своих программ, так что я впервые использую C ++, и я знаю, что между этими двумя языками есть некоторые различия.Я пытаюсь подсчитать количество избирателей в списке участников из класса «Журнал».

В C # я буду использовать

foreach(Member m in _members) {
    if(Member m is Voter) {
        votercount++;
    }
}

Однако я не уверен, еслив cpp эта реализация правильная?В моем файле Registry.h

class Logbook
{
private:
    std::list<Member> _members;

В моем файле Registry.cpp:

int Logbook::CandidateCount() {
  int membercount;
  for(Member m: _members) {
    if (Member* m=dynamic_cast<const Member*>(&Candidate)) membercount++;
  }
  return membercount;
}

В &Candidate отображается ошибка, в которой говорится, что идентификатор кандидата не определен.Это потому, что у журнала нет доступа к классу кандидата?

Любые ответы и помощь очень приветствуются.

Ответы [ 3 ]

0 голосов
/ 28 октября 2018

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

Далее вам необходимо сохранить указатели для членов вашегосписок, потому что в C++ полиморфизм работает только через указатели .Если список отвечает за удаление своих элементов (обычно), то вам следует использовать умный указатель, такой как std :: unique_ptr :

class Logbook {
public:
    int CandidateCount();

    // virtual destructor is (usually) important for polymorphic types
    virtual ~Logbook() = default;

    // store pointers in your list    
    std::list<std::unique_ptr<class Member>> members;
};

Затем вы можете перебирать этот список, пытаясь динамически приводит каждый указатель к типу, который вы хотите считать.Если он возвращает действительный указатель , то вы знаете, что он относится к этому типу.В противном случае будет возвращено nullptr:

class Member: public Logbook {};
class Candidate: public Member {};
class Voter: public Member {};

int Logbook::CandidateCount()
{
    int membercount = 0; // initialize this!!!!

    for(auto& m : members) { // use reference here to avoid making a copy

        if(dynamic_cast<Candidate*>(m.get()))
            membercount++;
    }

    return membercount;
}

Примечание: Если вы хотите сделать больше, чем просто считать ваших кандидатов васможет сохранить указатель, полученный из динамического приведения следующим образом:

class Candidate: public Member { public: void do_something(){} };

int Logbook::CandidateCount()
{
    int membercount = 0; // initialize this!!!!

    for(auto& m : members) { // use reference here to avoid making a copy

        if(auto c = dynamic_cast<Candidate*>(m.get())) {
            membercount++;

            // c is not nullptr and is type Candidate*    
            c->do_something(); // use your Candidate like this
        }
    }

    return membercount;
}
0 голосов
/ 28 октября 2018

Я бы постарался избежать использования RTTI и dynamic_cast s в C ++ и вместо этого придумал бы способ реализовать то, что вы делаете, используя другой подход, а именно, используя природу языка ООП.

У вас уже есть два класса, которые оба наследуют от Member, поэтому вы можете просто добавить метод CountMember(int& voterCount), который позволяет каждому члену регистрироваться самостоятельно. Затем вы просто вызываете этот метод для каждого члена, который у вас есть.Примерно так:

class Member {
public:
  virtual void countMember(int& voterCount) = 0;
};

class Candidate : public Member {
public:
  void countMember(int&) override {}
};

class Voter : public Member {
public:
  void countMember(int& voterCount) override {
    voterCount++;
  }
};

class Logbook {
private:
  std::list<Member> _members;
public:
  int CandidateCount() {
    int votercount = 0;
    for(auto& member : _members) {
      member.countMember(votercount);
    }
    return votercount;
  }
};

Это позволяет легко добавлять пользовательские поведения в случае добавления новых классов.

0 голосов
/ 28 октября 2018
int Logbook::CandidateCount()
{
    int membercount{};
    for(auto const &m : _members) {
       if (dynamic_cast<Member*>(m))
           ++membercount;
    }
    return membercount;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...