所以我有点像n00b并正在阅读有关new
,delete
和指针的内容,而且我确信在我的生命中我会忘记太多的删除。所以我想知道像下面这样的宏是否会比它的价值更麻烦。
#define withObject(ptr, value, BODY) \
{ \
ptr = value; \
BODY \
delete ptr; \
ptr=NULL \
}
这个宏会导致一些问题或以意想不到的方式表现吗?
编辑:oops我放弃了自由。谢谢大家的答案。
答案 0 :(得分:14)
不,不要这样做。它不会阻止内存泄漏或杂散指针。相反,请阅读智能指针。当前标准提供了auto_ptr形状的标准,但可以使用更多(和更好的标准),具体取决于您的C ++平台。
另外,我怀疑你可能过度使用new和delete - 它们应该在代码中很少使用。您应该更喜欢使用值。所以不要这样:
string * s = new string ( "foobar" );
....
delete s;
你应该写一下:
string s( "foobar" );
让编译器为你管理字符串的生命周期。
答案 1 :(得分:8)
无需重新发明轮子,您正在寻找smart pointers。
非常有用的Boost库具有smart pointer功能。
答案 2 :(得分:4)
google RAII idiom;它是一样的,但不是那么hacky;然后,您可以使用无处不在的智能指针(在不使用/范围时自动释放内存)将其应用于您的动态分配。
Boost包含最着名/最普遍的智能指针版本(seveal flavors)。
C ++标准总是有一种残缺的智能指针,名为auto_ptr
。这是一个有警告但有用的(RTFM!)。
C ++ 0x采用了几个Boost TR1类,包括最流行的智能指针(我希望我的措辞是正确的,因为标准通常对细节非常具体)
HTH
答案 3 :(得分:1)
您正在寻找智能指针模式。它是标准的C ++,并在this site详细解释。
答案 4 :(得分:1)
除了你真的应该使用智能指针这一事实(即使是低级auto_ptr
将用于你的目的),BODY可能存在问题。使用潜在的大部分代码作为类函数宏的参数有自己的陷阱。例如,如果BODY中有一个未加括号的逗号,那么BODY将变为两个参数。我不确定进一步的问题,因为我从来没有见过任何人尝试过。
不要在C ++中使用类似函数的宏。这很少值得。
答案 5 :(得分:0)
看起来您希望分配一个对象,对其执行一小段工作,然后将其删除。为此,我建议使用std :: auto_ptr。
答案 6 :(得分:0)
用于执行此类操作的惯用C ++方法不是使用宏,而是使用使用Resource Acquisition is Initialization的“智能指针”类。例如,Boost的scoped_ptr可以在你的宏有意义的环境中很好地工作。
我会在这里写一个智能指针类的草图 - 但我遗漏了很多细节。这只是为了让您了解它们的工作原理。使用scoped_ptr,他们没有留下任何东西。
template <typename T>
class smartptr<T> {
public:
smartptr() : ptr(new T) {}
smartptr(T* p) : ptr(p) {}
~smartptr() { delete ptr }
T& operator*() { return *ptr; }
T* operator->() { return ptr; }
private:
T* ptr;
}
答案 7 :(得分:0)
这个宏会导致一些问题或以意想不到的方式表现吗?
如果BODY抛出异常,则会跳过delete
。
解决方案是利用“RAII”成语。它是现代C ++编程中最重要的概念之一。
答案 8 :(得分:-2)
我认为更好的解决方案是制作分配和删除宏而不是包含所有内容。这是一个非常混乱,不是很有帮助的事情
当我在C中编程时,我通常会执行以下操作:
#define ALLOC_ARY(type, sz) (type*)calloc(sz, sizeof(type))
#define ALLOC_STR(sz) ALLOC_ARY(char, sz)
char *string = ALLOC_STR(128);
int *array = ALLOC_ARY(int, 20);
但是记住在香草C中释放只是其中的一部分:
free(string); string = NULL;
free(array); array = NULL;
编辑对于C ++,其他人建议的智能指针是一个很好的方法。