Композиция объекта — не может получить доступ к свойствам объекта

Привет, у меня есть проблема с составом объекта.
Класс CInvoice должен иметь внутри объект CCustomer, поэтому я создал конструктор, который требует клиента.

В файле Invoice.h есть строка:

CCustomer *customer;

И упомянутый конструктор выглядит так:

CInvoice::CInvoice(CCustomer Customer)
{
customer = &Customer;
}

Когда я пытаюсь напечатать имя клиента на счете, он возвращает случайные символы

CCustomer customer("McDonalds", "Boston, Massachusetts", 4);
CInvoice invoice(customer);

cout << "Customer:" << customer.GetName() << endl; //it prints "McDonalds"cout << "Invoice.Customer:" << invoice.customer->GetName() << endl; // it prints random characters

Правильно ли я реализовал композицию объектов?

Также у меня есть класс CInvoiceElement и у меня есть вопрос по этому поводу. Должен ли я создавать элементы счета-фактуры без создания объекта счета-фактуры или наоборот? Что более логично?

1

Решение

CInvoice::CInvoice(Customer customer)
{
customer = &Customer;
}

Когда вы вызываете этот метод, происходит следующее:

  • ты звонишь CInvoice(customer)
  • копия клиента помещается в стек в качестве аргумента
  • адрес копии присваивается Customer *customer;
  • конструктор заканчивается
  • стек освобождается, а аргумент клиента становится неверным указателем
  • Customer *customer таким образом указывает на мусор

Что вы должны сделать, это выделить Customer в куче и передать указатель, например.

Customer *customer = new Customer();
CInvoice *invoice = new CInvoice(customer);

CInvoice::CInvoice(Customer *customer) {
this->customer = customer;
}

Таким образом, ваш экземпляр клиента выделяется в куче, и он сохраняет область, в которой вы его объявляете. Пример, данный izomorphius, также работает, но Customer является локальным для области (он автоматически выделяется в стек), как только вы выходите из области действия указателя внутри CInvoice становится недействительным. Я надеюсь, вы понимаете разницу.

4

Другие решения

Вы должны передать указатель на CCustomer в конструкторе, в противном случае вы берете адрес копии CCustomer, который используется в качестве аргумента для конструктора.

Вот как должен выглядеть код:

CInvoice::CInvoice(CCustomer* _customer)
{
customer = _customer;
}....
CCustomer customer("McDonalds", "Boston, Massachusetts", 4);
CInvoice invoice(&customer);

cout << "Customer:" << customer.GetName() << endl; //it prints "McDonalds"cout << "Invoice.Customer:" << invoice.customer->GetName() << endl; // it prints random characters
4

это не изменит остальную часть вашего кода ..

CInvoice::CInvoice(CCustomer &Customer)
{
customer = &Customer;
}

а может ты нед?

В файле Invoice.h есть строка:

CCustomer customer;

И упомянутый конструктор выглядит так ??

CInvoice::CInvoice(const CCustomer &Customer)
: customer(Customer)
{
}
0
По вопросам рекламы [email protected]