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

C++ C++;can';无法从继承的类访问字段,c++,class,C++,Class,大家好,我有一个问题,我不能访问字段tablica[i]->help,在generauj函数中,它说这个字段在类任务中不存在。 我怎样才能做到呢 class Task { protected: string contents; int id_pyt; int nr_pyt; }; class Task4Answ : public Task { private: int help; public: Task4Answ(string content

大家好,我有一个问题,我不能访问字段tablica[i]->help,在generauj函数中,它说这个字段在类任务中不存在。 我怎样才能做到呢

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
            }
        }
    }
或者我现在正在做的项目还有其他解决方案。
谢谢您的帮助。

问题出在这行:

tablica[i]=new Task4Answ("0",0,0);
尽管您已经调用了
Task4Answ
构造函数,但也将
new
返回的内存地址分配给
Task
指针。实际上,您已将
Task4Answ
指针强制转换为
Task
指针。在下面的行中,C++只看到<代码> TabLICA[i] <代码>作为对<代码>任务< /C>指针的引用。您需要更改:

protected:
    Task *tablica[10];
    TaskCollection T1;
……为此:

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

这应该允许C++将<代码> TabCula<代码>作为一个数组,它是代码< TASK4ANSW 指针,而不是<代码>任务< /代码>指针。 编辑:看起来

help
也是私有的。您必须将
help
更改为public或将
TaskCollection::TaskCollection()
添加为好友。否则,C++将不允许你获得或设置<代码>帮助< /代码> .< 编辑: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;
        }
    }
}
稍后,为了访问
帮助
,您需要实现某种方式来检查
tablica[i]
是否是
Task4Answ
,而不是继承自
Task
的其他类的实例,可能通过在
任务
中实现名为
IsTask4Answ
的方法,该方法在
任务
中返回
false
,但在
任务4answ
中被重写为返回
True
。然后,您可以使用类似于
static\u cast
操作符的方法将指针转换回
Task4Answ
。换言之:

// 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.
}
//将这些函数添加到类定义中:
虚拟布尔任务::IsTask4Answ()常量{
返回false;
}
bool Task4Answ::IsTask4Answ()常量重写{
返回true;
}
//稍后,您可以执行以下操作:
if(tablica[i].IsTask4Answ()){
Task4Answ*t=静态(表[i]);
t->help;//同样,您必须将此更改为私有。
}
虽然我建议找出一种不需要进行任何转换的不同数据结构,但这将允许您访问
帮助


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

Task类型没有
help
成员。看起来
tablica
任务
的数组,但是
help
Task4Answ
.1中定义)
help
Task
中不存在,它存在于
Task4Answ
中。2) 即使它是私有的,
帮助
也是私有的,因此您无论如何都无法访问它。您可能希望在Task*/virtual int getHelp()=0中创建一个函数:
/*
/*在Task4Answ*/int getHelp override{return help;}
中,是否有可能使tablica成为一个任务数组,并从类中访问从Task继承的字段?@Darkd您的选项是:使
tablica
成为一个具体的
Task4Answ
数组,或者将
help
提升为
Task
接口的一部分。问题是我没有在主题中编写全部代码,因为有4个类继承自Task,它们的内容相同。我必须为这4个类创建一个对象数组。@DarekD啊,这改变了一切。我编辑了我的答案以涵盖该地区。如果可以重做数据结构而不需要强制转换,那通常更容易阅读和理解。非常感谢兄弟,现在我看到了我的错误。将更改某些数据结构以不执行此操作。再来一次,非常感谢!为了能够正确地将异构指针数组深度复制到基类,您需要向基类
Task
添加类似于
std::unique_ptr clone()const
的内容(并使析构函数
Task::~Task()
虚拟)。然后,在每个子类中重写它。即使您现在知道所有派生类都有相同的内容,但在将来扩展类层次结构时继续依赖这些内容也不是一个好主意。。。另外,顺便说一句,您通常应该更喜欢使用
std::vector
std::array
而不是原始的C样式数组。