对象组合 - 无法访问对象属性

时间:2013-01-08 14:07:03

标签: c++ object-composition

嗨我的对象组成有问题。 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类,并对此有疑问。我应该在没有创建发票对象的情况下创建发票元素,还是相反?哪个更符合逻辑?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:4)

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

当您调用此方法时会发生以下情况:

  • 您致电CInvoice(customer)
  • 将客户副本作为参数
  • 推入堆栈
  • 副本的地址已分配给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内的指针就变为无效。我希望你能有所作为。

答案 2 :(得分:0)

这不会改变你的其余代码..

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

但也许你已经知道了吗?

在Invoice.h文件中有一行:

CCustomer customer;

上面提到的构造函数看起来像这样??:

CInvoice::CInvoice(const CCustomer &Customer)
: customer(Customer)
{
}