0

For example,

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.

In Java we don't care the deletion of object. But I'm now doing it in C++. My question is, if I did the following in main()

Random random=new StdRandom();
AccGen accGen=new AccGen(random);

should I delete "random" in main(), or I should put it in the destructor of 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.

  • 4
    In Java, who is responsible for potential non-memory resources? – Deduplicator Nov 13 '19 at 20:56
  • 5
    It depends entirely on you. The concept is called *ownership* - the owner of the resource is responsible for cleaning up, but it's up to you to decide who is the owner. However, in modern C++ you shouldn't use `new` - use smart pointers like `std::unique_ptr` or `std::shared_ptr`. This way you have clear ownership and you *never* have to worry about deleting objects. – Yksisarvinen Nov 13 '19 at 20:57
  • How does `AccGen` know that pointer was created with a call to `new`? You could have given it the address of a non-allocated object, i.e. `Random random; AccGen accGen(&random);` -- So you can't simply equate C++ to Java or try to figure out what to do with C++ given how Java operates. – PaulMcKenzie Nov 13 '19 at 20:57
  • 1
    This is the curse of manual memory management. The responsible party is whoever's been specified by the design to be the responsible party. The general rule of thumb is to [not design your way into problems like this](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new). – user4581301 Nov 13 '19 at 20:58
  • 1
    Do you have `using Random = StdRandom*;` somewhere or what is `Random random=new StdRandom();` supposed to be doing? – Ted Lyngmo Nov 13 '19 at 21:03
  • Actually the code I posted was in Java. But I think my question is answered, the smart pointer. Thx everyone. – LeePai Chan Nov 14 '19 at 16:29

2 Answers2

3

In C++ we use smart pointers so then we don't care about delete.

Oblivion
  • 6,320
  • 2
  • 9
  • 30
2

My question is, if I did the following in main()

Random random=new StdRandom();
AccGen accGen=new AccGen(random);

The thing is: You dont. Random is a not a pointer type (unless it is a misleading alias for SomeOtherType*) but new returns you a pointer to the object it creates.

If you need dynamic allocations you can do it manually with raw pointers and take the full responsibility of deleteing things you created via new:

Random* random = new StdRandom();
AccGen* accGen = new AccGen(random);
// ... do something ...
delete accGen;
delete random;

It helps to get acustomed to the concept of ownership. If one object is responsible to manage the lifetime of a second instance, it is said to "own" that instance.

Further, resources are acquired in the constructor and released in the destructor (read about RAII if you want to know more). Hence, you could consider to let accGen take responsibility for deleting random in its destructor (*).

Doing this manually is neither recommended nor necessary. Use smart pointers. You can forget about new and delete if you just let smart pointers do the dirty work. There is no garbage in C++, though consistently using std::shared_ptr is probably what is closest to using a garbage collector.

Anyhow, if you do not need to allocate memory dynamically, then do not. C++ has value semantics. In C++ you get more than just references to objects, you get the objects.

int main {
    StdRandom random;
    AccGen accGen{random};
    // ... use accGen ...
}   // <- end of scope

No need to delete anything. Objects on the stack get their destructor called when going out of scope.

(*) = If a function gets passed a raw pointer, it is not expected to take ownership of the pointed to object. The function cannot know if it is allocated on the stack or dynamically.

463035818_is_not_a_number
  • 64,173
  • 8
  • 58
  • 126
  • Probable typo: To keep the same (assumed) pointer syntax, `AccGen accGen{random};` should be `AccGen accGen{&random};` – user4581301 Nov 14 '19 at 00:17
  • @user4581301 actually it was on purpose to have the last example without any pointers. Very likely a `StdRandom` is not copyable, but i didnt want to bloat the answer with more discussion – 463035818_is_not_a_number Nov 14 '19 at 10:19
  • 1
    @LeePaiChan Smart pointer *could* be the answer. Unfortunately there is no way to be sure from the example given in the question. Nothing in the example suggests you need more than an [Automatic variable](https://en.wikipedia.org/wiki/Automatic_variable). Remember that unlike in Java [you do not have to `new` objects](https://isocpp.org/wiki/faq/value-vs-ref-semantics). Where possible let the runtime take care of the management for you. – user4581301 Nov 14 '19 at 19:13