0

我正在学习 C++ 并且遇到了指针问题。
这个简单的项目包含一张发票,其中包含指向客户的指针。

课程:

class Customer {
    string name;
public:
    Customer(string name) { this->name = name; };
    string getName() { return name; };
    void changeName(string name) { this->name = name; };
};

class Invoice {
    Customer * customer;
public:
    Invoice(Customer *customer) { this->customer = customer; };
    Customer getCustomer() { return *customer; };
};

主要的:

Customer *customer1 = new Customer("Name 1");
Invoice invoice1(customer1);

cout << invoice1.getCustomer().getName() << endl; //Return:Name 1;

我如何使用 Customer::changeName(string name) 来完成这项工作:

(...) changeName("Name 2");

cout << invoice1.getCustomer().getName() << endl; //Return:Name 2;

我不知道我应该使用什么来更改客户的名称。或者我在类发票中做错了什么。

为什么要通过 Invoice 更改名称?
所以我可以在项目开始变大之前学习如何使用指针。
稍后我将有一个发票向量和一个客户向量。从发票或客户向量中获取指向客户的指针应该是相同的。

谢谢你,
爱德华多

4

3 回答 3

7
Customer getCustomer() { return *customer; };

应该

Customer& getCustomer() { return *customer; };

因为在第一种情况下,您复制了客户对象,因此您的更改发生在一个被丢弃的临时对象中......

在第二个中,您将返回对您创建的对象的引用。

改名

string newName = "Edu";
invoice1.getCustomer().changeName( newName );
于 2012-11-03T23:43:49.590 回答
2

如果你想让这大大加强,我在这里采取了这样的自由。客户和发票声明都进行了重大更新。将它们与您现有的代码进行比较。不要只是将其复制到您的代码中,因为它肯定会破坏很多东西。相反,看看它,看看它是否对你有意义:

class Customer 
{
    string name;

public:
    Customer(const string& name) : name(name) {};

    const string& getName() const { return name; };
    void changeName(const string& name) { this->name = name; };
};

class Invoice 
{
    const Customer& customer;

public:
    Invoice(const Customer& customer) : customer(customer) {};

    const Customer& getCustomer() const { return customer; };
};

一般来说(通常情况下,无论如何)您需要通过指针传递对象的唯一时间是对象指针接收器是否有机会接受 NULL 作为有效值。否则使用引用或智能指针。支持多态访问的对象指针数组无法承受(即使是智能指针 ftw),这通常是一个很好的规则。

做出的重大改变:

  • 除非特别需要非 const 访问,否则使用 const 引用
  • 类具有初始化列表以确保成员变量的最佳构造,事实上现在对于 Invoice 是必需的,因为必须在初始化列表中初始化客户引用成员。

主要的

Customer customer1("Name 1");
Invoice invoice1(customer1);

// note: invoice now only allows you to obtain a const-reference
//  to the customer of the invoice. As such, you can only fire
//  const-members on the returned customer reference.
cout << invoice1.getCustomer().getName() << endl; //Return:Name 1;

// without the const-ness of the getCustomer() member and the reference
//  it returns, you would have been able to do this:
//
//  invoice.getCustomer.changeName("newname");
//
// As it is written now, you can only change a customer name from
//  a non-const customer reference (or pointer), and in doing so, 
//  *all* invoices for that customer will reflect this change.
customer1.changeName("Name 2");

// note: the invoice was not changed, but the customer it references
//  was, and we should see that change now.
cout << invoice1.getCustomer().getName() << endl; //Return:Name 2;

我希望这能给您一些想法,让您了解如何在以后的项目中限制和强化对象访问。

于 2012-11-03T23:55:44.030 回答
1

Invoice中,返回指向Customer自身的指针,而不是其取消引用值的副本:

Customer* getCustomer() { return customer; };

然后你可以像这样更改名称,更改将影响实际Customer对象:

invoice1.getCustomer()->changeName("Name2")
于 2012-11-03T23:52:18.100 回答