的 foo.h中 的
#include "class1.h"
class foo{
private:
class1* class1ObjectPointer;
public:
foo();
virtual ~foo();
void foomethod();
}
foo.cpp (版本1)
#include "foo.h"
foo::foo()
{
this->class1ObjectPointer = new class1();
}
foo::~foo()
{
if( this->class1ObjectPointer != NULL ){
delete class1ObjectPointer;
this->class1ObjectPointer = NULL;
}
}
foo::foomethod(){
*(this->class1ObjectPointer) = some_method();
//suppose some method returns an object of class1
}
foo.cpp (版本2)
#include "foo.h"
foo::foo()
{
this->class1ObjectPointer = NULL;
}
foo::~foo()
{
if( this->class1ObjectPointer != NULL ){
delete class1ObjectPointer;
this->class1ObjectPointer = NULL;
}
}
foo::foomethod(){
class1 object;
object = some_method();
//suppose some method returns an object of class1
this->class1ObjectPointer = new class1(object); // copy constructor
}
在以下情况下哪个指针分配更好:
您是否会建议其他更好的方式来完成我在这些片段中所做的事情?
答案 0 :(得分:2)
无论任何赋值如何,类的实例都具有常量。 如果将成员变量分配给某个指针,则实例的大小不会更改。内存中的一些垃圾(如果你先将其初始化,则为NULL值)将被其他一些已分配对象的地址替换。
答案 1 :(得分:2)
根据您的第一个示例重新分配对象比分配新对象可能更好(更有效,更容易避免内存泄漏) - 如第二个示例中的内存泄漏所示。
看起来很像你根本不需要指针;只需在你的班级中嵌入一个对象:
class foo {
private:
class1 class1Object;
public:
// implicit constructors, assignment and destructor are fine
void foomethod() {class1Object = some_method();}
};
你的第二种情况没有意义 - 特定类的对象大小都相同。
如果你真的需要存储一个指针(也许是因为你需要多态),那么处理它的最简单方法是使用智能指针:
class foo {
private:
std::unique_ptr<class1> class1ObjectPointer;
public:
foo() : class1ObjectPointer(new class1) {}
// implicit copying and destructor are fine
foomethod() {*class1ObjectPointer = some_method();}
// or, if not assignable, class1ObjectPointer.reset(new class1(*some_method()));
};
如果您真的想自己管理它,那么您需要根据Rule of Three覆盖默认的复制构造函数和复制赋值运算符,确保在重新指定指针时删除旧对象,并且小心异常安全。并且无需在删除前检查NULL
,也无需在析构函数中指定NULL
。
答案 2 :(得分:0)
if ptr != NULL
检查在delete
前面是多余的,因为它会在内部进行检查。
哪些变体更好取决于具体情况。两者都有它们的用途。
根本不要使用指针。如果必须,请使用std::unique_ptr
(需要C ++ 11)或boost::shared_ptr
。
在任何情况下,构造函数中的成员都应初始化,而不是已分配。也就是说,写如下:
foo::foo() : class1ObjectPointer(new class1) { }