Проблема проектирования наследования C++

В C++ я хочу иметь массив абстрактного типа Query с функцией calcScore(), которая является чисто виртуальной функцией.
И у меня есть два класса, которые не являются абстрактными: ConQuery и DisQuery, которые реализуют функцию calcScore.

Для этого я определил массив следующим образом:

vector<Query*> m;

и я повторяю и вызываю функцию следующим образом:

for (vector<Query*>::const_iterator it1 = index.begin() ;it1 != index.end() ; it1++)
{
     cout << (*it1)->CalcScore() << endl; 
}

Я получаю сообщение об ошибке при вызове чисто виртуальной функции Query. Как мне сделать так, чтобы он вызывал функцию ConQuery или функцию DisQuery по полиморфному типу? Благодарю.

4 ответа

Решение

Вы уверены, что CalcScore реализован в ConQuery и DisQuery? Я попробовал это:

#include <iostream>
#include <vector>

class Query{
public:
    virtual int CalcScore() = 0;
};

class Query2 : public Query
{
public:
    virtual int CalcScore()
    {

        return 2;
    }
};

class Query3 : public Query
{
public:
    virtual int CalcScore()
    {

        return 3;
    }
};

int main(int argc, char* argv[])
{

    std::vector<Query*> m;
    m.push_back(new Query2());
        m.push_back(new Query3());
    for (std::vector<Query*>::const_iterator it1 =  m.begin() ;it1 !=  m.end() ; it1++)
    {
        std::cout  << (*it1)->CalcScore();
    }
}

и он отлично работает под моим VS2012.

Также я использовал это много раз в некоторых из моих проектов.

Может быть, вы пытаетесь push_back элемент Query (а не con/dis)?

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

struct Query {
   virtual void f() = 0;
   Query() {
      f();                // !!
   }
   ~Query() {
      f();                // !!
   }
};

Обратите внимание, что компиляторы обычно отмечают приведенный выше код как ошибку, но не смогут обнаружить его, если вызов не находится непосредственно в конструкторе / деструкторе, если, например, вы передаете ссылку на объект другой функции, которая выполняет вызов.

+ Изменить

for (vector<Query>::const_iterator it1 = index.begin() ;it1 != index.end() ; it1++)

в

for (vector<Query *>::const_iterator it1 = index.begin() ;it1 != index.end() ; it1++)

Я мог что-то пропустить, но это работает для меня: я уже знаю, что я не инициализирован и т. Д.;-)

#include "stdafx.h"
#include <vector>


class Query
{
public:
    int i;
    void virtual CalcScore() = 0;
};

class ConQuery :public Query
{
public:
    int i;
    void virtual CalcScore() {i++;}

};


int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<Query*> index;
    ConQuery b;

    index.push_back(&b);

    for (std::vector<Query*>::const_iterator it1 = index.begin() ;it1 != index.end() ; it1++) 
    {      
        (*it1)->CalcScore();
    } 

    return 0;
}
Другие вопросы по тегам