用于自动销毁堆对象的宏

Macro for auto destroy heap objects

本文关键字:对象 用于      更新时间:2023-10-16

这不是我正在工作的实际代码。但是这段代码可以用来清楚地解释我的问题。

我有一个名为"OnCallFunction"的函数,其中有一些新的对象作为输入,应该在"OnCallFunction"中删除。在每一个点,我应该返回,我需要在那里添加删除代码。我认为这不是正确的做法。以这种方式,这应该被记住,并放在每一个回报,这将在未来做。如果代码不像下面这样简单,我可能会忘记插入删除部分。

#include <iostream>
#include <stdlib.h>
using namespace std;
class Student
{
public:
        Student(){}
        ~Student(){}
        int GetID(){return rand();}
};
int OnCallFunction(Student* pStudent)
{
        int iValue = pStudent->GetID();
        if (iValue == 5)
        {
                delete pStudent;
                return 90;
        }
        if (iValue == 67)
        {
                delete pStudent;
                return 8709;
        }
        if (iValue == 234)
        {
                delete pStudent;
                return 78;
        }
        if (iValue == 343)
        {
                delete pStudent;
                return 9832;
        }
        if (iValue == 678)
        {
                delete pStudent;
                return 876;
        }
        delete pStudent;
        return -1;
};
int main(int argc, const char** argv)
{
        Student* pStudent = new Student();
        OnCallFunction(pStudent);
};
因此,我开发了一个宏来自动销毁堆对象。这是使用宏(AUTO_DESTROY) 修改后的代码
#include <iostream>
#include <stdlib.h>
using namespace std;
#define AUTO_DESTROY(ClassType, Variable, DeleteStatement)
class AD##ClassType##Variable
{
public:
        AD##ClassType##Variable(ClassType* pData) {Variable=pData;};
        ~AD##ClassType##Variable() {DeleteStatement;};
private:
        ClassType* Variable;
};
AD##ClassType##Variable oAD##ClassType##Variable(Variable)
class Student
{
public:
        Student(){}
        ~Student(){}
        int GetID(){return rand();}
};
int OnCallFunction(Student* pStudent)
{
        AUTO_DESTROY(Student, pStudent, delete pStudent);
        int iValue = pStudent->GetID();
        if (iValue == 5)
        {
                return 90;
        }
        if (iValue == 67)
        {
                return 8709;
        }
        if (iValue == 234)
        {
                return 78;
        }
        if (iValue == 343)
        {
                return 9832;
        }
        if (iValue == 678)
        {
                return 876;
        }
        return -1;
};
int main(int argc, const char** argv)
{
        Student* pStudent = new Student();
        OnCallFunction(pStudent);
};

现在我的问题是,

1) Does this has any performance/maintainability/code quality impact rather than deleting in each return?
2) In this macro it creates a class inside the function. So will than cause multiple declarations if we use the same macro, same class type, same variable name in multiple cpp files? Agree that I can test it.
3) Are there any ideas or pre-built things to do this in easier way?

注:

请不要建议在堆中创建"Student"作为堆栈变量,或者将函数输出保存在变量中,只在最后返回。:)

不要使用宏,也不要使用原始指针。使用unique_ptr来保存分配的对象,并将函数更改为:

int OnCallFunction(std::unique_ptr<Student> pStudent)
{
        int iValue = pStudent->GetID();
        if (iValue == 5)
        {
                return 90;
        }
        if (iValue == 67)
        {
                return 8709;
        }
        if (iValue == 234)
        {
                return 78;
        }
        if (iValue == 343)
        {
                return 9832;
        }
        if (iValue == 678)
        {
                return 876;
        }
        return -1;
};
int main(int argc, const char** argv)
{
        std::unique_ptr<Student> pStudent(new Student());
        OnCallFunction(std::move(pStudent));
};

OnCallFunction()退出时,将自动删除被管理的Student对象

boost的作用域出口已经实现了您想要的功能。您可以查看该实现或使用开箱即用。

示例:

#include <boost/scope_exit.hpp>
#include <cstdlib>
#include <cstdio>
#include <cassert>
int main() 
{
    std::FILE* f = std::fopen("example_file.txt", "w");
    assert(f);
    BOOST_SCOPE_EXIT(f) {
    // Whatever happened in scope, this code will be
    // executed  and  file  will be correctly closed.
        std::fclose(f);
    } BOOST_SCOPE_EXIT_END
    // Some code that may throw or return.
    // ...
}

使用这个功能,你实际上是在指定独立的"RAII析构函数动作"。

在使代码更清晰、更干净的地方使用,避免在所有功能更容易合并(或已经合并)到类的析构函数中时使用。