Шаблон функции вызова членов класса с функцией обратного вызова - PullRequest
2 голосов
/ 20 июня 2010

У меня проблемы с передачей функции обратного вызова из класса при вызове функции шаблона. Вот пример кода:

sortedlist.h

#ifndef _sortedlist_h
#define _sortedlist_h

#include <vector>    

template <typename ElemType>
class SortedList {
public:
    SortedList(int (*compare)(ElemType a, ElemType b));
    ~SortedList();

    void push(ElemType newElem);
    ElemType pop();

private:
    std::vector<ElemType> v;
    int (*cmp) (ElemType first, ElemType second);
    void Sort();
};


template <typename ElemType>
SortedList<ElemType>::SortedList(int (*compare)(ElemType a, ElemType b)) {
    cmp = compare;
}

template <typename ElemType>
SortedList<ElemType>::~SortedList() {
}

template <typename ElemType>
void SortedList<ElemType>::push(ElemType newElem) {
    v.push_back(newElem);
    Sort();
}

template <typename ElemType>
ElemType SortedList<ElemType>::pop() {
    ElemType next = v.back();
    v.pop_back();
    return next;
}

template <typename ElemType>
void SortedList<ElemType>::Sort() {
    for (int i=v.size()-1; i>0; i--) {
        if(cmp(v[i], v[i-1]) < 0) {  //compare function
            ElemType temp = v[i];
            v[i] = v[i-1];
            v[i-1] = temp;
        }
        else return;
    }
}

#endif

game.h

#ifndef _game_h
#define _game_h

#include <string>
#include "sortedlist.h"

class Game {
public:
    Game() {};
    ~Game() {};
    void addPlayer(std::string name, int score);
    std::string getWinner();

    struct Player {
        std::string name;
        int score;
    };

    //compare function
    int highScore(Player one, Player two);

private:    
    SortedList<Player> list(highScore);

};

#endif

game.cpp

#include "game.h"

void Game::addPlayer(std::string name, int score) {
    Player newEntry;
    newEntry.name = name;
    newEntry.score = score;
    list.push(newEntry);    
}

std::string Game::getWinner() {
    return list.pop().name;
}

//compare function
int Game::highScore(Player one, Player two) {
    if (one.score == two.score) return 0;
    if (one.score > two.score) return 1;
    return -1;
}

Образец основного:

#include <iostream>
#include "game.h"
using namespace std;

int main () {
    Game pacman;
    pacman.addPlayer("Beavis", 100);
    pacman.addPlayer("Butthead", 200);
    cout << pacman.getWinner() << endl; 
}

Когда я компилирую его в XCode, я получаю сообщение об ошибке "рекорд" не является типом ". Я также попытался вывести Player и highScore за пределы класса с похожими результатами. Что мне делать вместо этого?

1 Ответ

4 голосов
/ 20 июня 2010

В C ++ вы не можете инициализировать членов класса на месте.Это необходимо сделать в списке инициализатора конструктора

class Game {
public:
    Game():list(highScore) {};
    ~Game() {};

    //compare function
    static int highScore(Player one, Player two);

private:    
    SortedList<Player> list;
};

Функция должна быть объявлена ​​как static в определении класса, так как SortedList вызывает ее без указателя *this, как обычная функция,

Производительность действительно не нужна для функции сравнения, потому что вы всегда копируете два элемента для сравнения при передаче их в качестве аргументов.Лучше сделать тип функции сравнения для получения const-ссылок и соответственно изменить подпись highScore

int (*compare)(ElemType const& a, ElemType const& b);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...