2017-08-10 74 views
-1

只是不明白,如何實現這個原型。 我試圖創建容器的基類的對象的Worker* 迭代容器,對象將調用虛擬方法->work()。根據派生類的指針應該叫他自己重寫功能C++繼承鑄造,父母對孩子和回

class Worker { 
public: 
    Worker(...) { ... } 
    virtual void work() { /* justWork(); */ } 
}; 

class Professional : public Worker { 
public: 
    Professional(...) { ... } 
    virtual void work() override { /* workGood(); */ } 
}; 

class Workplace { 
public: 
    void train(Worker* worker) { 
     /* need to save object properties and 
      set pointer to derived class */ 

     // *worker = Professional(worker); 
     worker = new Professional(worker); 
     /* following compiles fine, but when I call worker->work() 
      outside of this body it calls simple Worker::work() 
      when I need to call Professional::work() */ 
    } 
    void fire(Worker* worker) { 
     /* need to save object properties 
      set pointer value back to 
      Parent/Base class Worker */ 

     // *worker = Worker(worker); 
    } 
}; 

int main() 
{ 
    Workplace workplace; 
    Worker* worker = new Worker(); 

    worker->work(); // Worker::work() => justWork() 

    workplace.train(worker); 
    worker->work(); 
    // should be Professional::work() => workGood(), 
    // but it calls Worker::work() => justWork() 

    workplace.fire(worker); 
    worker->work(); // Worker::work() => justWork() 

    return 0; 
} 
+0

你在這裏通過'Worker *'值:void train(Worker * worker){'。我建議使用'std :: unique_ptr '來傳遞它們。 – user0042

+0

對於'Workplace :: train',您通過值*傳遞指針*。這意味着你有一個原始指針的*副本,所以這個分配只會改變副本,而不是你在'main'函數中創建的原始副本。 –

+0

@Someprogrammerdude所以我嘗試過: 'Workplace :: train(Worker&worker){worker = Professional(); } workplace.train(* worker);' 也沒有成功,我還在做錯嗎? –

回答

0

我不能評論低於50代表,所以我必須寫一個答案。 也許你解決了問題,但你也需要釋放職場::火車()和工作場所::火(),你在main()已分配的內存空間:

Worker* worker = new Worker(); 

否則,你會得到內存泄漏。

class Workplace { 
public: 
    void train(Worker*& worker) { 
     Worker* temp = worker; 
     /* A temporary pointer to the allocated object. */ 

     worker = new Professional(temp); 
     /* Allocating memory for new object. */ 

     delete temp; 
     /* Destroying previous object. */ 
    } 
    void fire(Worker*& worker) {    
     Worker* temp = worker;    
     worker = new Worker(temp); 
     delete temp; 
    } 
}; 

Workplace::fire()您分配*worker = Worker(worker);是行不通的。 worker仍然指向相同的類型(在這種情況下:到Professional)。 另外,如果要通過Worker*指針刪除Professional以避免內存泄漏,則需要在Worker類中使用虛擬析構函數。

class Worker { 
public: 
    /* other member functions */ 
    virtual ~Worker() {} 
}; 
+0

aww,我能覆蓋指針,它是通過正確的傳遞參數聲明在main中,而不是釋放內存嗎? –

+0

_overwriting_是什麼意思?也許這個:'* worker = Professional(worker)'?因爲它不會工作。如果您希望指針指向**另一個類型**,則必須爲新對象分配內存,並刪除前一個。 –

+0

另外,最好將引用傳遞給構造函數而不是指針,如下所示:'Professional(const Worker&)'和'Worker(const Professional&)'。並以這種方式調用它們:'worker = new Professional(* temp)'和'worker = new Worker(* temp)'。如果通過引用傳遞,則不會創建指針的副本。 –

0

它的參數傳遞錯誤的,固定的:

void train(Worker*& worker) { ... } 
void fire(Worker*& worker) { ... } 

現在它的工作原理, TNX到@Someprogrammerdude @ user0042