哪个指针赋值更好(C ++)

时间:2012-03-02 15:10:32

标签: c++ pointers memory-management constructor copy-constructor

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
}

在以下情况下哪个指针分配更好:

  1. class1的对象始终具有固定大小(例如,其中包含固定变量的类)
  2. class1的对象可能包含可变大小的成员(例如,其中包含矩阵的类可能具有不同的大小)

  3. 您是否会建议其他更好的方式来完成我在这些片段中所做的事情?

3 个答案:

答案 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)

  1. if ptr != NULL检查在delete前面是多余的,因为它会在内部进行检查。

  2. 哪些变体更好取决于具体情况。两者都有它们的用途。

  3. 根本不要使用指针。如果必须,请使用std::unique_ptr(需要C ++ 11)或boost::shared_ptr

  4. 在任何情况下,构造函数中的成员都应初始化,而不是已分配。也就是说,写如下:

    foo::foo() : class1ObjectPointer(new class1) { }
    

    这使用initialisation list