C++继承设计问题

3
在c++中,我想要一个抽象类型为Query的数组,其中包含calcScore()函数,该函数是一个纯虚函数。
并且我有两个非抽象类ConQuery和DisQuery,它们实现了calcScore函数。

为了实现这一点,我定义了以下数组:

vector<Query*> m;

and I iterate and call the function like this:

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

我遇到了一个错误,对于Query的纯虚函数调用会报错。如何通过多态类型来调用ConQuery或DisQuery的函数呢?谢谢。


你如何初始化那个 vector - K-ballo
vector<Query*> m; 但是 vector<Query>::const_iterator... 那么容器的真实类型是什么?无论如何,错误表明您正在从 Query 的构造函数/析构函数中调用 Query 的虚函数... - David Rodríguez - dribeas
4个回答

3

如果您尝试从类型的构造函数或析构函数中调用纯虚函数(其中最终派生类型尚未构建/已被销毁),则此错误只能在语言中发生:

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

请注意,编译器通常会将上述代码标记为错误,但如果调用不是直接在构造函数/析构函数中进行的话,例如您将对象的引用传递给执行调用的其他函数,则编译器将无法检测到该错误。

2
你确定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下,它能够很好地工作。

在我的一些项目中,我使用了它许多次。

也许你尝试向后推一个查询项(而不是连接/断开)?


编译器应该发出警告,如果您尝试创建一个Query值,因为您不能创建一个抽象类型的对象... - David Rodríguez - dribeas
他遇到的问题不是编译器问题吗? - Clément
编译器不允许您创建抽象类的实例,这意味着它会在您调用纯虚函数之前失败。 - David Rodríguez - dribeas

1

更改

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

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

星号在那里,忘记写在这里了。 - tomermes

1
我可能漏掉了什么,但这对我有效: 我已经知道i没有初始化等等;-)
#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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接