如何管理和处理仅在堆上创建的类的对象

How to manage and process objects of a class only created on the heap?

本文关键字:创建 对象 处理 何管理 管理      更新时间:2023-10-16

我有一个对象类和objectmanager类,该类应该将指针固定在堆上创建的对象上,并且负责管家。即,(我不想有指向临时对象的指针,例如,当对象通过值传递给函数时)。我想对ObjectManager类中的项目进行一些进程,然后发布内存。

请考虑以下文件:

" object.h"文件

#pragma once
#include<algorithm>
#include "ObjectManager.h"
class ObjectManager;
class Object{
private:
int value;
static bool heap_flag;
public:
    Object() {
        if (heap_flag) {
            heap_flag = false;
            ObjectManager::vo.push_back(this);
            }
        }
    ~Object() {}
    void* operator new (size_t sz){
        heap_flag = true;
        return malloc(sz);
    }
    void setValue(int v) { value = v; }
};

和" objectmanager.h"

#pragma once
#include "Object.h"
#include <vector>
using namespace std;
class Object;
class ObjectManager{
private:
    ObjectManager() {}
public:
static vector <Object*> vo;   // vector that holds pointers to all objects created on heap
static void releaseObjects() {
    size_t index = 0;
        for (auto o : vo){
            // iterate through the vector and delete the object create on heap
            delete o;
            vo[index] = NULL;
            index++;
        }

    }

};

最终在客户端代码中:

#include <iostream>
#include "Object.h"
#include "ObjectManager.h"
using namespace std;
bool Object::heap_flag = false;
vector<Object*> ObjectManager::vo;
void process_Heap_objects (vector<Object*>) {
// ... code to iterate through the elements of a vector and do some process

}
int main() {
Object o; // created on stack
Object* po = new Object(); // created on heap
ObjectManager::vo[0]->setValue(100);
process_Heap_Objects(ObjectManager::vo); 
ObjectManager::releaseObjects();
return 0;
}

当我编译此文件时,我会在VS2013->"警告C4150:删除指针到不完整类型的'对象'中的删除;无称为destructor1> objectmanager.h:请参阅"对象"的声明

该代码可以正常编译并按预期工作。

两个问题:

1-警告是什么意思?

2-这是一个好设计吗?有更好的方法可以实现这一目标吗?您的想法是什么?

您无法在向前声明的类上调用destuructor。

您必须将destructor调用放在汇编单元中,其中可以看到destructor的声明(例如,您#cimclude the Object.h)。

另外,风格技巧:

  • 按价值通过:
    • 如果该对象不会被方法突变或复制,请通过const ref foo (const Object& bar) {}
    • 通过
    • 如果对象要突变但不被方法复制,请通过参考foo (Object& bar) {}
    • 通过
    • 如果该对象将通过该方法复制,请通过Value
    • 传递
    • 如果该方法拥有该对象,请通过指针
    • 通过
  • Pragma曾经是标准的正式一部分,很少在当前一代编译器中提供更快的编译。建议使用的大多数样式指南包括警卫:

    #ifndef SOME_NAME
    #define SOME_NAME
    ... body ...
    #endif
    

您的问题是您在标题文件中定义和实现ObjectObjectManager。这会创建一个循环依赖性,因为每个标头文件都包含另一个。

一种更好的方法是仅在CPP文件中的标题和方法中具有类定义。

您收到的警告是由于未定义的对象引起的。因为您有#pragma once,所以您看不到应该看到的错误(循环依赖性的效果。)这阻止了对象管理员查看对象类是如何定义的。