-1

I'm writing part of a customer database that handles making new customers and selling them items. In "Customer.h", I have the struct:

struct Customer {
    String name;
    int bottles;
    Customer(String);
    Customer(void) { name = "__invalid__"; }
};

I have a class in the file "CustomerDB.h"

class CustomerDB {
private:
    Customer* data; // an array of Customer objects (allocated on the heap)
    int capacity; // size of the array on the heap
    int length; // number of valid customers actually in the array

public:
    CustomerDB(void);

There's a constructor, in "CustomerDB.cpp"

Customer::Customer(string name) {
    this->bottles = 0;
    this->name = name;
}

I create *an object in another function (which is in "CustomerDB.cpp")

Customer& CustomerDB::operator[](string name) {
     Customer Customer(name); 
     return Customer;

And there's an object of CustomerDB:

CustomerDB database; (Which is in another cpp file which handles the purchases).

The string input works. The object is created. There's no issues there. So I have 2 problems, one of which is because of the other.

  1. I need to make a new non-Local Customer object in this function (stored into the non-Local Database), and
  2. Return the reference to it. But the constructor I just called doesn't give me a reference. It just makes it, as it should. I'm unintentionally making a local object instead of one that's added to the "main" database. As a result, the reference is nothing useful.

If I try return Customer; it says that "Customer does not refer to a value."

Any help/advice is appreciated.

WesLee
  • 1
  • 1
  • 1. You are trying to return a variable which is an auto scope.. So that is not going to work. 2. Why are you doing this in the overloaded array indexing operator ([]) ? And even if you want to do that i dont think indexing operator can accept a string argument.. – Arun Kaliraja Baskaran Aug 04 '20 at 15:56
  • 1
    I assume `CustomerDB` has some collection of `Customer` objects? Then you can return a reference to one of those objects, but not to a temporary object created in the function. – cigien Aug 04 '20 at 15:56
  • Either allocate some member and return a reference to that, or return a value. But I think more context on the design is needed. – underscore_d Aug 04 '20 at 15:56
  • 1
    This sounds like you want a `std::map` or similar. – PaulMcKenzie Aug 04 '20 at 15:58
  • The `&` in `Customer&` does not indicate an address. `&` has three different meanings in C++, depending on context. – molbdnilo Aug 04 '20 at 16:02
  • Does this answer your question? [C++ Returning reference to local variable](https://stackoverflow.com/questions/4643713/c-returning-reference-to-local-variable) – Czarking Aug 04 '20 at 16:07
  • Don't return a reference, just return a Customer object. `Customer CustomerDB::operator[](string name) { return {name}; }` – Eljay Aug 04 '20 at 16:17
  • I apologize, I used the wrong terminology. I want to create an object, and I want the reference to that object so I can give it to another function. I just don't know how to get it. – WesLee Aug 04 '20 at 16:18
  • To answer that, I need to know who owns the object. From your code snippet, no one owns the object, so it should not be returned by reference. A more complete [mcve] would be helpful, otherwise it is a lot of guesswork and may be an XY problem. – Eljay Aug 04 '20 at 16:23
  • Unrelated: A [Member Initializer List](https://en.cppreference.com/w/cpp/language/constructor) may help you simplify your constructor code. – user4581301 Aug 04 '20 at 16:29
  • @WesLee C++ favors value semantics. You usually pass *the value* of an object around. It sounds like you want to create a `Customer` and return a pointer to it. This can work, you would use the return type `std::unique_ptr` and return the result of `std::make_unique(...)`. But unless you have a reason to use this strategy you should prefer to return a `Customer` object directly. The return type would just be `Customer` with no `&`. – François Andrieux Aug 04 '20 at 16:33
  • @FrançoisAndrieux An `operator[]` usually returns a reference. – Asteroids With Wings Aug 04 '20 at 16:34
  • @AsteroidsWithWings Usually, yes. But it doesn't look like that is what OP wants. It is being used as a `Customer` factory here. Every call to `operator[]` produces a new `Customer`, even if the same value of `name` is provided. Whether or not that is a good idea is another matter. Edit : After reading the comments to your answer, I'm not sure that is the case. Maybe the provided code just isn't representative of their actual goal. – François Andrieux Aug 04 '20 at 16:36
  • @FrançoisAndrieux Agreed, it probably isn't. I'm considering the name `CustomerDB` too - probably not a factory. – Asteroids With Wings Aug 04 '20 at 16:38

1 Answers1

2

I need to return the address of this freshly made Customer

No, you need to return a reference to it.

but the constructor I just called

You never call constructors. You declared an object.

doesn't give me an address. How do I find/obtain this new Customer and return its address?

You take the address of an object like this:

return &Customer;

But to return a reference, it's simply:

return Customer;

But this isn't going to work!

You'd be returning a reference to a local variable. It's about to go out of scope, leaving the reference dangling.

So, you need to rethink your choices with this design.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
  • Okay, I know that an object was made. And I assume that it isn't local to the function that it was made in. How am I supposed to get the reference of an object in any function? In other words, what other method would I use to obtain the reference of an object? – WesLee Aug 04 '20 at 16:21
  • 1
    @WesLee you haven't provided enough information to give a concrete solution, but `[]` suggests that the object should be stored somewhere with longer life, perhaps in a `std::vector` or `std::map` of `Customer`s that is a `CustomerDB` member variable. That way the `Customer` can be safely returned by reference and you can look it up and use it again later. – user4581301 Aug 04 '20 at 16:26
  • @WesLee If it's not really a local variable, then you do as shown. But realistically we'd need to know what your code _actually_ is then to give a proper answer. – Asteroids With Wings Aug 04 '20 at 16:34