在 C++ OOP 中,谁负责删除传递给构造函数的对象
In C++ OOP, who is responsible to delete object passed to constructor
例如,
I have an account generator class need a random method to decide
username and password. Random has many ways to implement, so it is an
interface with many subclass. Account generator class accept Random
object in constructor.
在Java中我们不关心对象的删除。但我现在正在用 C++ 来做。
我的问题是,如果我在 main()
中执行了以下操作
Random random=new StdRandom();
AccGen accGen=new AccGen(random);
我应该在main()中删除"random",还是应该把它放在AccGen的析构函数中?
Edit:
Even after the question is being answered very well, I think I may
still state the reason that why do I use pointer, in order to help
somebody facing the same problem.
The reason I use pointer, is to apply many patterns like Factory and
Behavior. Non-pointer variable seems not able to be an Interface with
pure virtual method, which cannot present overrides.
In a design view, I think the creator of an object is always
responsible for its deletion. That is why it makes me confused. All
the caller wants, it an AccGen object. I passed a random object is to
decide the implementation of Random, inside AccGen. Then Random object
is not a participant in caller's level, then why should the caller be
responsible for its deletion. But the fact is, in some case, the
random is useful in the following actions in caller's level. The given
example is really just an example.
After a study of smart pointer, Unique pointer really is the solution
of my problem. It makes pointer become more specific, in terms of to state
the purpose of creating such pointer.
To summarize, if an object is useful after passed to constructor, then
the type would be pure pointer and with no deletion in destructor. If
the object is useless in caller's level, then the type should be
unique pointer.
在 C++ 中我们使用 smart pointers 所以我们不关心删除。
My question is, if I did the following in main()
Random random=new StdRandom();
AccGen accGen=new AccGen(random);
事实是:你不知道。 Random
不是指针类型(除非它是 SomeOtherType*
的误导性别名)但是 new
returns 你是指向它创建的对象的指针。
如果您需要动态分配,您可以使用原始指针手动完成,并全权负责 delete
通过 new
创建的内容:
Random* random = new StdRandom();
AccGen* accGen = new AccGen(random);
// ... do something ...
delete accGen;
delete random;
这有助于习惯所有权的概念。如果一个对象负责管理第二个实例的生命周期,则称 "own" 该实例。
此外,资源在构造函数中获取并在析构函数中释放(如果您想了解更多信息,请阅读 RAII)。因此,您可以考虑让 accGen
负责在其析构函数 (*) 中删除 random
。
既不推荐也不需要手动执行此操作。使用 smart pointers。如果你只是让智能指针做这些肮脏的工作,你可以忘记 new
和 delete
。 C++ 中没有垃圾,尽管始终使用 std::shared_ptr
可能最接近于使用垃圾收集器。
总之,如果你不需要动态分配内存,那就不要。 C++ 具有值语义。在 C++ 中,您获得的不仅仅是对对象的引用,您还获得了对象。
int main {
StdRandom random;
AccGen accGen{random};
// ... use accGen ...
} // <- end of scope
无需删除任何内容。堆栈上的对象在超出范围时会调用其析构函数。
(*) = 如果一个函数被传递给一个原始指针,它不应该获得指向对象的所有权。该函数无法知道它是在堆栈上分配还是动态分配。
例如,
I have an account generator class need a random method to decide username and password. Random has many ways to implement, so it is an interface with many subclass. Account generator class accept Random object in constructor.
在Java中我们不关心对象的删除。但我现在正在用 C++ 来做。 我的问题是,如果我在 main()
中执行了以下操作Random random=new StdRandom();
AccGen accGen=new AccGen(random);
我应该在main()中删除"random",还是应该把它放在AccGen的析构函数中?
Edit:
Even after the question is being answered very well, I think I may still state the reason that why do I use pointer, in order to help somebody facing the same problem.
The reason I use pointer, is to apply many patterns like Factory and Behavior. Non-pointer variable seems not able to be an Interface with pure virtual method, which cannot present overrides.
In a design view, I think the creator of an object is always responsible for its deletion. That is why it makes me confused. All the caller wants, it an AccGen object. I passed a random object is to decide the implementation of Random, inside AccGen. Then Random object is not a participant in caller's level, then why should the caller be responsible for its deletion. But the fact is, in some case, the random is useful in the following actions in caller's level. The given example is really just an example.
After a study of smart pointer, Unique pointer really is the solution of my problem. It makes pointer become more specific, in terms of to state the purpose of creating such pointer.
To summarize, if an object is useful after passed to constructor, then the type would be pure pointer and with no deletion in destructor. If the object is useless in caller's level, then the type should be unique pointer.
在 C++ 中我们使用 smart pointers 所以我们不关心删除。
My question is, if I did the following in main()
Random random=new StdRandom(); AccGen accGen=new AccGen(random);
事实是:你不知道。 Random
不是指针类型(除非它是 SomeOtherType*
的误导性别名)但是 new
returns 你是指向它创建的对象的指针。
如果您需要动态分配,您可以使用原始指针手动完成,并全权负责 delete
通过 new
创建的内容:
Random* random = new StdRandom();
AccGen* accGen = new AccGen(random);
// ... do something ...
delete accGen;
delete random;
这有助于习惯所有权的概念。如果一个对象负责管理第二个实例的生命周期,则称 "own" 该实例。
此外,资源在构造函数中获取并在析构函数中释放(如果您想了解更多信息,请阅读 RAII)。因此,您可以考虑让 accGen
负责在其析构函数 (*) 中删除 random
。
既不推荐也不需要手动执行此操作。使用 smart pointers。如果你只是让智能指针做这些肮脏的工作,你可以忘记 new
和 delete
。 C++ 中没有垃圾,尽管始终使用 std::shared_ptr
可能最接近于使用垃圾收集器。
总之,如果你不需要动态分配内存,那就不要。 C++ 具有值语义。在 C++ 中,您获得的不仅仅是对对象的引用,您还获得了对象。
int main {
StdRandom random;
AccGen accGen{random};
// ... use accGen ...
} // <- end of scope
无需删除任何内容。堆栈上的对象在超出范围时会调用其析构函数。
(*) = 如果一个函数被传递给一个原始指针,它不应该获得指向对象的所有权。该函数无法知道它是在堆栈上分配还是动态分配。