C ++无法从继承的类访问字段

时间:2017-06-28 18:17:20

标签: c++ class

大家好,我有一个问题,我无法访问字段tablica [i] - >帮助,在generuj函数中,它说这个字段不存在于类Task中。 我怎样才能实现它?

class Task
{
  protected:
     string contents;
     int id_pyt;
     int nr_pyt;
};

class Task4Answ : public Task
{
private:
    int help;
public:
    Task4Answ(string contents1, int id,int nr,int help1)
    {
        contents=contents1;
        id_pyt=id;
        nr_pyt=nr;
        help=help1;
    }
};

class TaskCollection
{
    protected:
        Task *collection[60];
    public:
        friend class Generator;
        TaskCollection()
        {
          collection[0] = new Task4Answ("Ile jest por roku w Polsce? \na) 1 \nb) 2 \nc) 3 \nd) 4",1,0);
          collection[1] = new Task4Answ("Kto wygral tegoroczny Roland Garros? \na) Federer \nb) Djokovic \nc) Nadal \nd) Thiem",1,1);
class Generator
{
protected:
    Task *tablica[10];
    TaskCollection T1;
public:
    Generator(){}
    void Generuj()
    {
            if(T1.collection[x]->id_pyt==1)
            {
                tablica[i]=new Task4Answ("0",0,0);
                tablica[i]->contents=T1.collection[x]->contents;
                tablica[i]->id_pyt=T1.collection[x]->id_pyt;
                tablica[i]->nr_pyt=T1.collection[x]->nr_pyt;
                tablica[i]->help=T1.collection[x]->help; //here is the problem
            }
        }
    }

或者也许我现在正在做一些项目的其他解决方案。 谢谢你的帮助。

1 个答案:

答案 0 :(得分:2)

问题出在这一行:

tablica[i]=new Task4Answ("0",0,0);

虽然您已调用Task4Answ构造函数,但您还将new返回的内存地址分配给Task指针。实际上,您已将Task4Answ指针转换为Task指针。在接下来的行中,C ++仅将tablica[i]视为对Task指针的引用。你需要改变:

protected:
    Task *tablica[10];
    TaskCollection T1;

......对此:

protected:
    Task4Answ *tablica[10]; // Task was changed to Task4Answ
    TaskCollection T1;

这应该允许C ++将tablica视为Task4Answ指针数组,而不是Task指针。

编辑:看起来help也是私有的。您必须将help更改为公开或将TaskCollection::TaskCollection()添加为朋友。否则,C ++将不允许您获取或设置help

编辑:OP补充说tablica[i]可能包含从Task继承的其他类的实例。在这种情况下,你可以这样做:

void Generuj()
{
        if(T1.collection[x]->id_pyt==1)
        {
            Task4Answ* newTask = new Task4Answ("0",0,0);
            newTask->contents=T1.collection[x]->contents;
            newTask->id_pyt=T1.collection[x]->id_pyt;
            newTask->nr_pyt=T1.collection[x]->nr_pyt;
            newTask->help=T1.collection[x]->help; // You will still have to change this from being private.
            tablica[i] = newTask;
        }
    }
}

稍后,为了访问help,您需要实现某种方式来检查tablica[i]是否为Task4Answ而不是继承的其他类的实例来自Task,可能是通过在Task IsTask4Answ中实施一个方法,该方法在false中返回Task但在True中被覆盖以返回Task4Answ 1}}。然后,您可以使用Task4Answ运算符之类的指针将指针强制转换回static_cast。换句话说:

// Add these functions to the class definitions:
virtual bool Task::IsTask4Answ() const {
    return false;
}
bool Task4Answ::IsTask4Answ() const override {
    return true;
}
// Later, you can do this:
if(tablica[i].IsTask4Answ()){
    Task4Answ* t = static_cast<Task4Answ*>(tablica[i]);
    t->help; // Again, you'll have to change this from being private.
}

虽然我建议您找出不需要进行任何投射的不同数据结构,但这样您就可以访问help

请注意上面第一个函数中的virtual关键字;它允许函数动态绑定,这意味着代码将检查是否在运行时而不是在编译时调用Task::IsTask4Answ()Task4Answ::IsTask4Answ()