I have a problem with undersending how work override operator new. I have the base class Task with a overridden operator new:
void* operator new(size_t bytes, const allocate_continuation_proxy& p);
This operator is used for allocate a new task and set private fields from current working task. allocate_continuation_proxy& is refer to current task.
class allocate_continuation_proxy;
class Task {
public:
virtual ~Task() {
}
void* operator new(size_t size) {
return ::operator new(size);
}
void* operator new(size_t bytes, const allocate_continuation_proxy& p);
allocate_continuation_proxy& allocate_continuation() {
return *reinterpret_cast<allocate_continuation_proxy*>(this);
}
virtual Task* Compute() = 0;
inline Task* Continuation() {
return _continuation;
}
inline void Continuation(Task& task) {
_continuation = &task;
}
inline void ContinuationAsNull() {
_continuation = nullptr;
}
protected:
Task() {
}
private:
Task* _continuation;
Ct* _cancellationToken;
};
class allocate_continuation_proxy {
public:
Task& allocate(size_t size) const;
};
inline Task& allocate_continuation_proxy::allocate(size_t size) const {
Task& t = *((Task*)this);
Task* c = (Task*) ::operator new(size);
c->CancellationToken(nullptr);
c->Continuation(*t.Continuation());
c->PendingCount(0);
t.ContinuationAsNull();
return *c;
}
inline void* Task::operator new(size_t bytes, const allocate_continuation_proxy& p) {
return &p.allocate(bytes);
}
I try to execute this code:
class C0 : public Task {
public:
//C0() {
//}
Task* Compute() override {
std::cout « "C0 is computing..." « std::endl;
Task* c = Continuation()
c->Compute(); //if constuctor C0() is not been to define, this line throw exception because "c" = nullptr, but "c" has to point on instance of C2
return nullptr;
}
};
class C2 : public Task {
public:
Task* Compute() override {
std::cout « "C2 is computing..." « std::endl;
return nullptr;
}
};
class C1 : public Parallel::Task {
public:
Task* Compute() override {
std::cout « "C1 is computing..." « std::endl;
C0& c = *new (allocate_continuation()) C0();
c.Compute();
return nullptr;
}
};
int main() {
C1& c1 = *new C1();
c1.Continuation(*new C2());
c1.Compute();
return 0;
}
My problem is into the this line:
C0& c = *new (allocate_continuation()) C0();
If constuctor C0() is not been to define, refer "c" does not have _continuation that has been set into the allocate_continuation_proxy::allocate(size_t size). But If I define a constructor into the class C0, refer "c" will have a _continuation. I don`t understand why? And How can I get the correct behavior without defining a constructor into the derived class?
Aucun commentaire:
Enregistrer un commentaire