2017-02-16 6 views
1

私はポインタのベクトルを格納することができ、要求に基づいてポインタのベクトルを削除することができるデザインパターンを探しています。後で使用される最初の関数によって作成されたポインタを格納するために使用するデザインパターンは何ですか?

これは私の既存のコードパスです。ここで

### implementation.h 

class A { 
    A() {} 
    private: 
    void AggregateMetrics(); 
    void FlushMetrics(); 
    X* x_; 
    Y* y_; 
}; 

class X { 
    public: 
     void CreateFiles(vector<B*> *objects, string path); 
}; 

class B { 
    B() { 
    m_ = 0, n_ = 0; 
    } 
    private: 
     int m_, n_; 
}; 

### implementation.cpp 


void A::A() { 
    x_ = new X(); 
    y_ = new Y(); 
} 

void A::AggregateMetrics() { 
} 

void A::FlushMetrics() { 
    vector<B*> objects; 
    x_->CreateFiles(&objects, path); 
    // In my new code, we are going to move the above two lines 
    // to AggregateMetrics() and i need to find a way to store 
    // the vector<B*>objects; 
    y_->Flush(objects); 
    return; 
} 

void X::CreateFiles(vector<B*> *objects, string path) { 
    CHECK(objects.empty()); 
    for (int i = 0; i < 10; i++) { 
     objects->push_back(new B()); 
    } 
} 

は私の新しいコードです: ### implementation.h

class A { 
    A() {} 
    private: 
    void AggregateMetrics(); 
    void FlushMetrics(); 
    X* x_; 
    Y* y_; 
}; 

class X { 
    public: 
     void CreateFiles(vector<B*> *objects, string path); 
}; 

class B { 
    B() { 
    m_ = 0, n_ = 0; 
    } 
    private: 
     int m_, n_; 
}; 

class PointerManager { 
    public: 
     PointerManager() {} 
     void SetPointers(vector<B*>& objects); 
     vector<B*> GetPointers(); 
    private: 
     vector<B*>objects_; 
}; 

### implementation.cpp 
PointerManager::SetPointers(vector<B*>& objects) { 
    objects_ = objects; 
} 

vector<B*> PointerManager::GetPointers() { 
    return objects_; 
} 

void A::A() { 
    x = new X(); 
    y = new Y(); 
    mgr_ = new PointerManager(); 
} 

void A::AggregateMetrics() { 
    vector<B*> objects; 
    x->CreateFiles(&objects, path); 
    mgr_->SetPointers(objects); 
} 

void A::FlushMetrics() { 
    auto objects = mgr_->GetPointers(); 
    y->Flush(objects); 
    return; 
} 

void X::CreateFiles(vector<B*> *objects, string path) { 
    CHECK(objects.empty()); 
    for (;;) { 
     objects->push_back(new B()); 
    } 
} 

私は基本的に作成した後、これらのポインタを保持することができ、必要なときに返すことができますPointerManagerと呼ばれる新しいクラスを作成しています。ここで理想的なデザインは何でしょうか?デザインパターンを提案できますか?

+0

これはhttp://codereview.stackexchange.com/questions/tagged/c%2b%2bに投稿することをお勧めします。 例を完全にコンパイル可能にする必要があります(現在は完全ではありません)。 –

+0

完了。適切なクラスメンバーを持つようにコードを編集しました。 – user1159517

+0

生ポインタ=不良。 unique_ptrを使用してください。コンストラクタのbody = badのポインタを初期化しています。初期化リスト構築を使用する。 –

答えて

2

smart pointerを使用して、メモリリークを防ぐためにコンテナに保管することをお勧めします。

#pragma once 
#include <iostream> 
#include <string> 
#include <vector> 
#include <memory> 
#include <cassert> 
class B { 
    public: 
     B() { 
      m_ = 0, n_ = 0; 
     } 
    private: 
     int m_, n_; 
}; 
class Y{ 
    public: 
     Y(){} 
     ~Y(){} 
     void Flush(std::vector<std::unique_ptr<B>>& objects); 
}; 
class X { 
    public: 
     void CreateFiles(std::vector<std::unique_ptr<B>> &objects, std::string path); 
}; 
class PointerManager { 
    public: 
     PointerManager() {} 
     void InsertPointer(std::unique_ptr<B> &object); 
     void SetPointers(std::vector<std::unique_ptr<B>> &objects); 
     std::vector<std::unique_ptr<B>> &GetPointers(); 
    private: 
     std::vector<std::unique_ptr<B>> objects_; 
}; 
class A { 
    public: 
     A(); 
     void AggregateMetrics(); 
     void FlushMetrics(); 
    private: 
     X* x_; 
     Y* y_; 
     PointerManager* mgr_; 
}; 

implementation.cpp

#include "implementation.hpp" 

void Y::Flush(std::vector<std::unique_ptr<B>>& objects){ 
    for(int i =0;i<objects.size();i++){ 
     objects[i].release(); 
    } 
} 

void X::CreateFiles(std::vector<std::unique_ptr<B>> &objects, std::string path) { 
    assert(objects.empty()); 
    for (int i = 0; i < 5;i++) { 
     std::cout << "for loop in CreatesFiles " << std::endl; 
     objects.emplace_back(new B); 
    } 
} 

void PointerManager::InsertPointer(std::unique_ptr<B> &object) { 
    std::cout << "InsertPointer " << std::endl; 
    objects_.push_back(std::move(object)); // object now belongs to PointerManager 
} 

void PointerManager::SetPointers(std::vector<std::unique_ptr<B>> &objects){ 
    for(int i=0;i<objects.size();i++){ 
     this->InsertPointer(objects[i]); 
    } 
} 

std::vector<std::unique_ptr<B>>& PointerManager::GetPointers() { 
    std::cout << "Get Pointers" << std::endl; 
    return objects_; 
} 

A::A() { 
    x_ = new X(); 
    y_ = new Y(); 
    mgr_ = new PointerManager(); 
} 

void A::AggregateMetrics() { 
    std::cout << "Aggregate Metrics " << std::endl; 
    std::string path = "."; 
    std::vector<std::unique_ptr<B>> objects; 

    x_->CreateFiles(objects, path); 
    mgr_->SetPointers(objects); 
} 

void A::FlushMetrics() { 
    std::cout << "Flush Metrics " << std::endl; 
    y_->Flush(mgr_->GetPointers()); 
    return; 
} 

CLANG 3.4.2およびg ++ 4.9と罰金この実行:

ここでは、スマートポインタに

implementation.hppを使用してデザインのバージョンがあります。 3 -std = C++ 11フラグを使用します。

2

あなたが基本的に求めているのは、「ポインターを使用して自分のメモリ管理を実装するにはどうすればいいですか?

これに対する答えは、そうではありません。

現代C++は、アプリケーションコードの肩から「管理」負担が多いsmart pointersunique/shared pointersなどの概念を提供しています。

だから答えは:ステップバック、2017年に利用可能なすべての手段でC++を使用する方法を学ぶ。 20年前のように書かれたコードを書くのではなく、

関連する問題