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

Which pointer assignment is better (C++)

本文关键字:C++ 更好 赋值 指针      更新时间:2023-10-16

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. 类1的对象总是具有固定的大小(例如,其中包含固定变量的类)
  2. 类1的对象可能具有可变大小的成员(例如,具有矩阵的类,该矩阵可能具有不同大小)

你会建议其他更好的方法来做我在这些片段中所做的事情吗?

根据第一个示例重新分配对象可能比分配新对象更好(更高效,更容易避免内存泄漏),正如第二个示例中的内存泄漏所示。

看起来你根本不需要指针;只需在类中嵌入一个对象:

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()));
};

如果你真的想自己管理它,那么你需要根据"三条规则"覆盖默认的复制构造函数和复制赋值运算符,确保在重新分配指针时删除旧对象,并注意异常安全。并且在删除之前不需要检查NULL,也不需要在析构函数中指定NULL

类的实例大小不变,与任何赋值无关。如果将成员变量分配给某个指针,则实例的大小不会更改。只有内存中的一些垃圾(或者NULL值,如果您先初始化它的话)会被其他分配对象的地址所取代。

  1. CCD_ 3检查在CCD_。

  2. 这些变体中哪一个更好取决于具体情况。两者都有各自的用途。

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

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

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

    这使用了一个初始化列表。