我正在寻找一种可以存储指针矢量的设计模式,并可以根据需求移除指针矢量。
这是我现有的代码路径。
### 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 :(得分:2)
我建议使用smart pointer并将它们存储到容器中以避免任何内存泄漏。
这是使用智能指针
的设计版本implementation.hpp:
#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;
}
使用-STd = c ++ 11 flag,CLANG 3.4.2和g ++ 4.9.3运行正常。
答案 1 :(得分:2)
您基本上要问的是:&#34;如何使用原始指针实现自己的内存管理?&#34;
答案就是:你没有。
现代C ++提供了诸如smart pointers或unique/shared pointers之类的概念,这些概念占用了很多&#34;管理&#34;来自应用程序代码的负担。
所以这里的真正的答案是:退一步,学习如何使用2017年提供的所有方法使用C ++;而不是编写像15年前那样的代码。