用于自动销毁堆对象的宏

时间:2014-07-12 07:55:12

标签: c++ macros

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

我有一个名为" 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?

NB:

请不要建议创建&#34;学生&#34;作为堆中的堆栈变量或将函数输出保存在变量中并仅在结尾处返回。 :)

2 个答案:

答案 0 :(得分:3)

不要使用宏,也不要使用原始指针。使用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));
};

Student退出时,将自动完成对托管OnCallFunction()对象的正确删除。

答案 1 :(得分:3)

提升范围退出已实施您想要的功能。您可以查看该实现或直接使用它。

示例:

#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.
    // ...
}

使用this功能,您几乎可以指定独立的“RAII析构函数”。

使用它可以使代码更清晰,更清晰,并避免在所有功能更容易合并(或已经存在)类的析构函数中。

相关问题