2017-08-10 3 views
-1

このプロトタイプの実装方法を知りません。 私は基本クラスのオブジェクトのコンテナを作成しようとしていますWorker* コンテナを反復すると、オブジェクトは仮想メソッド->work()を呼び出します。 、user0042C++の継承キャスト、親と子、後ろ

+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

@ @Someprogrammerdudeする TNX

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

今では動作します:派生クラスによってはポインタで、間違ったパラメータ渡し、固定した彼自身の上書き機能

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

aww、メモリを解放するのではなく、正しい渡しパラメータでメインで宣言したポインタを上書きできますか? –

+0

_overwriting_とは​​どういう意味ですか?たぶんこれは: '* worker = Professional(worker)'?それは動作しないためです。 **別のタイプ**を指すポインターにする場合は、新しいオブジェクトにメモリを割り当て、前のオブジェクトを削除する必要があります。 –

+0

また、 'Professional(const Worker&)'と 'Worker(const Professional&)'のように、ポインタの代わりにコンストラクタへの参照を渡す方が良いでしょう。 'worker = new Professional(* temp)'と 'worker = new worker(* temp) 'と呼びます。参照渡しの場合は、ポインタのコピーを作成しません。 –

0

を呼び出す必要があります私は50人以下の人にはコメントできないので、答えを書く必要があります。 はたぶん、あなたは問題を修正しますが、あなたは)(メインに割り当てられている職場::電車()と職場::火(のメモリ空間)解放する必要があります:あなたは意志、そうでない場合

Worker* worker = new Worker(); 

をメモリリークを取得します。あなたの割り当て*worker = Worker(worker);は動作しませんWorkplace::fire()

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; 
    } 
}; 

workerは同じタイプ(この場合は:Professionalに)を指しています。 また、メモリリークを回避するためにProfessionalからWorker*ポインタを削除する場合は、Workerクラスに仮想デストラクタが必要です。

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