未分配来自默认字段初始化的值

时间:2019-05-16 23:42:11

标签: c++ oop inheritance constructor initialization

我目前正在为我的操作系统类从事实验室研究,但我很难理解为什么未分配我在类的默认字段初始化中指定的值。我有以下调度程序类:

class LOOK : SSTF {
public:
    io_req* pop() override;
};

该继承自此调度程序:

class SSTF : protected IOSched {
public:
    virtual io_req* pop() override;
    virtual void push(io_req* new_req) override;
protected:
    io_req* left_pop();
    io_req* right_pop();
    int dir;
    LinkedList left;
    LinkedList right;   
};

其中IOSched是具有pop()和push()方法以及curr_req字段的纯虚拟类,这是LinkedList类:

class LinkedList {
public:
    io_req* pop();
    void push(io_req* new_req);
    void push_in_order(io_req* new_req);
    io_req* top() const;
    void reset_dist(io_req* new_curr);
private:
    void insert_between(io_req_node* new_prev, io_req_node* new_next, io_req_node* new_node);
    io_req_node* head = nullptr;
    io_req_node* tail = nullptr;
};

据我对C ++的理解,当我这样分配一个新的LOOK对象时:

sched = (IOSched*)(new LOOK());

我将得到一个指向堆分配的LOOK对象的指针,该对象将包含一个SSTF对象,该对象将包含两个LinkedList对象,left和{{1 }},将使用righthead作为tail进行初始化。

但是,由于某种原因,我得到nullptr的值为0x203d1,而其余的值为left.head。这仅在0x0被初始化为sched对象时发生,而不是在LOOK初始化时发生(在实验中,我必须实现一些不同的算法)。

谢谢!

2 个答案:

答案 0 :(得分:1)

sched = (IOSched*)(new LOOK());

您不能将指针强制转换为该类之外的受保护基类:

class A{};

class B : protected A {
    void foo(){
        B b;
        A * a = &b; // this is ok
    }
};

int main() {
    A * a = new B; // this is not
}

改为使用公共继承-在传统的面向对象的情况下,这几乎总是您想要的。

此外,不要在c ++中使用c样式强制转换。如果您使用static_cast,它将继续向您大喊大叫,因为您应该被大吼:)

答案 1 :(得分:-3)

非静态成员初始化是C ++ 11的扩展(请参见here)。

由于成员不是静态的,因此必须在构造函数初始化列表中对其进行初始化:

class LinkedList {
public:
    LinkedList() : head(nullptr), tail(nullptr) {}
    io_req* pop();
    void push(io_req* new_req);
    void push_in_order(io_req* new_req);
    io_req* top() const;
    void reset_dist(io_req* new_curr);
private:
    void insert_between(io_req_node* new_prev, io_req_node* new_next, io_req_node* new_node);
    io_req_node* head ; // useless = nullptr;
    io_req_node* tail , // useless = nullptr;
};

或切换到C ++ 11或更高版本。