在类中存储指针 我学习C++,并且在指针方面有问题。 这个简单的项目包含一个发票,发票上有一个指向客户的指针

在类中存储指针 我学习C++,并且在指针方面有问题。 这个简单的项目包含一个发票,发票上有一个指向客户的指针,c++,class,variables,pointers,C++,Class,Variables,Pointers,课程: 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:

课程:

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;
Main:

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*customer1=新客户(“名称1”);
发票发票1(客户1);
库特
应该是

Customer& getCustomer() { return *customer; };
因为在第一种情况下,您复制了customer对象,因此您的更改发生在一个临时对象中,该对象被丢弃

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

改名

string newName = "Edu";
invoice1.getCustomer().changeName( newName );

发票
中,返回指向
客户
本身的指针,而不是其解引用值的副本:

Customer* getCustomer() { return customer; };
然后,您可以像这样更改名称,更改将影响实际的
客户
对象:

invoice1.getCustomer()->changeName("Name2")

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

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),这通常是一个很好的遵循规则

发生的重大变化:

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

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;
客户客户1(“名称1”);
发票发票1(客户1);
//注意:发票现在只允许您获取常量参考
//给发票的客户。因此,你只能开火
//返回的客户参考上的const成员。

cout以及我应该如何在Main中调用函数changeName,以便修改此指针的内容?+1用于返回引用,将可能的segfault定位到
Invoice
类。