C++ 对于重置功能,哪种做法更好?

C++ 对于重置功能,哪种做法更好?,c++,memory,reset,C++,Memory,Reset,Edit:MyClass只是一个例子。问题实际上是关于如何重置类的部分成员。在我的实际案例中,类更复杂,数据将长达一百万。此外,我还有复制/移动命令和操作符,在我的示例中省略了它们 我有一节课 class MyClass{ double *data; int data_length; MyClass() : data(nullptr), data_length(0){} ~MyClass(){ if(data !=

Edit
MyClass
只是一个例子。问题实际上是关于如何重置类的部分成员。在我的实际案例中,类更复杂,
数据
将长达一百万。此外,我还有复制/移动命令和操作符,在我的示例中省略了它们

我有一节课

class MyClass{
     double *data;
     int data_length;         

     MyClass() : data(nullptr), data_length(0){}

     ~MyClass(){
         if(data != nullptr){
             delete[] data;
         }
     }
}
现在我想添加一个新的成员函数
reset()
。 以下哪项是更好的做法

(a)

(b)


看起来,(a)更安全,但更耗时,(a)的客户端在调用
reset()
后必须手动删除\u data中的temp
。(b) 效率更高,但客户端可能会在外部数据中删除

最好复制数据,而不要依赖外部世界来获取这些内容,尤其是当您有一个析构函数删除类未分配的内存时。

只有一个数据成员:

std::vector<double> data;

如果您有其他数据收集,您可以为每个数据收集执行类似的操作—每个数据收集都可以高效、独立地更新。

为什么要“重置”对象?(还有,为什么没有
std::ptr
?)在第一个变体中,您缺少分配。无论如何,您已经发现了为什么引入移动语义的问题。什么更好取决于您的用例。
std::vector
看起来更合适,但是,是的,为什么要使用自己的内存管理?这些东西存在于标准库中;你只需要使用它,而不是重新实现它。(旁注:
delete nullptr;
什么都不做,所以不需要检查它)@JBL就是一个例子。如果一个类有多个数据指针,我想更改其中一个。我想重置它,而不是重建整个类。如果您的类MyClass是一个资源类,请使用所有常规成员尽可能简单地编写它。然后您将使用MyClass的实例,而不是无风险的双指针。如果这不是一个练习,请使用std::vector。如果数据的大小足够长,则可能需要将
reset
拆分为两个重载,分别使用左值和右值引用。优化器不能总是更改代码,您需要特定的操作,这些操作将被执行。问题在于,如果内部缓冲区已经足够大,可以容纳新值,并且调用方正在使用左值(即,调用
重置
后,他们仍然需要这些值)。数据可以就地复制,但使用by value参数会强制进行分配、复制元素、销毁旧元素并释放旧缓冲区[类型为
double
意味着销毁不是op,但与我无关],其中单个
memcpy
将work@DavidRodríguez dribeas:我被出卖了——谢谢你陪我走过这一切。干杯。“删除他们没有分配的内存”。。。。这就是析构函数的好处,不是吗?通常,内存是在构造函数(或其他地方)中分配的,很少在析构函数中分配。@tobi303我不明白你的意思。我没有提到在析构函数中分配内存的问题。哦,我明白了,在“内存未分配”中,“它”代表类。所以我想指出的是,在OP的情况b)中,MyClass释放了它没有分配的内存,这对我来说是一种代码味道。
MyClass::reset(double* in_data, int in_length){
    if(data != nullptr){
        delete[] data;
    }
    data = in_data;
    data_length = in_length;
}
std::vector<double> data;
void reset(std::vector<double>&& new_data) { data = std::move(new_data); }
void reset(const std::vector<double>& new_data) { data = new_data; }
myClass.reset(get_new_data_vector());  // moves returned vector

std::vector x = { ... };
myClass.reset(x); // do a full "deep" copy
myClass.reset(std::move(x));  // explicitly allow move from named local var