我目前正在为我的操作系统类从事实验室研究,但我很难理解为什么未分配我在类的默认字段初始化中指定的值。我有以下调度程序类:
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 }},将使用right
和head
作为tail
进行初始化。
但是,由于某种原因,我得到nullptr
的值为0x203d1
,而其余的值为left.head
。这仅在0x0
被初始化为sched
对象时发生,而不是在LOOK
初始化时发生(在实验中,我必须实现一些不同的算法)。
谢谢!
答案 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或更高版本。