1

I have implemented a class called Customer, here is the header file: which worked perfectly.

Now, Based on my Customer class, I would like to implement a BST tree to store customer information, But I should need a node class which contains Customer object, pointers to left children and right children. I have troubles about implement Node class correctly. Especially for the Customer object.

class Customer {
public:
    Customer(string,char,int);
    string get_name();
    char get_initial();
    int get_account();
    void set_account(int);
    bool operator<(Customer & c);
    bool operator<=(Customer & c);
    bool operator>(Customer & c);
    bool operator>=(Customer & c);
    bool operator==(Customer & c);
    bool operator!=(Customer & c);

private:
    string name;
    char initial;
    int account;
    friend ostream& operator<<(ostream & os,  Customer & c);
};

#ifndef NODE_H_
#define NODE_H_

#include "Customer.h"

class Node {
public:
    Customer parent;
    Node* left;
    Node* right;
};

#endif /* NODE_H_ */

The error showed: is implicitly deleted because the default definition would be ill-formed:

Meraj al Maksud
  • 1,528
  • 2
  • 22
  • 36
Van
  • 11
  • 2
  • There is no way to construct a `Node` without default-constructing a `Customer`. However, there is no way to default-construct a `Customer`. You've provided only on mechanism for `Customer` construction, and it requires arguments. Regardless, the posted code here (and *only* this posted code) generates no such error. The code you chose *not* to include (where you're creating `Node` objects) is where things ultimately start going off the rails. – WhozCraig Jul 13 '19 at 18:29
  • If you read the entire error message it should tell you all of the above, you might need to look in the build output window of your IDE – Alan Birtles Jul 13 '19 at 18:49

1 Answers1

2

The problem here is about the default constructor of the Node class. The default constructor, is automatically generated in class, if there is no other user-defined constructors. So, the default constructor tries to generate the default values to all of the class's members, and run into problems when it tries to call the default constructor of the object Customer which is no exists (because the constructor Customer(string,char,int); exists, and there is no user-defined default constructor for the Customer class). There are several solutions you can use (Sorted from most recommended to least recommended, in this particular case. in other cases this rate might have some changes):


Solution 1 (Recommended)

Define a constructor in the Node class, that use the non-default constructor of the Customer class member parent:
class Node {
public:
    Node(string name, char c, int age) : parent(name, c, age) {}
    Customer parent;
    Node* left;
    Node* right;
};

Solution 2

Define default constructor for Customer class:

class Customer {
public:
    /*...*/
    Customer();
    /*...*/
}

Why doesn't it the most recommended way in this case? It solves the compiler's error with less code than the most recommended way, so why not choosing this way? This way have logical issue- What does an empty customer mean? How do you know when a Customer object is empty? You can see my answer here: C++ vector of struct allocated on stack to get an idea of identify an object that have been created without any user-defined data. Those validations are a little bit more complicated than forcing the user to set some data ahead.

However - this way might be the best way when there are no logical issues like the one I mentioned before, or whenever there is no need to deal with validations, or in cases where the validations are worth the choosing in this solution.


Solution 3 (Highly not recommended)

Define parent in Node class as pointer (so the default value will be nullptr).

Why not choosing this option? This option might be the easiest and fastest way to make the compiler error disappear- However it will force you to handle pointers of pointers and memory management all the way in your program, and will make your life much harder than the other solutions (after the compiler error gone - segfault (What is a segmentation fault?) are much more annoying than compiler errors).

Coral Kashri
  • 3,436
  • 2
  • 10
  • 22
  • Also worth adding that's there's nothing wrong with combining solution 1 and solution 3. Solution 2 is an anti-solution, definitely not recommended, but probably very attractive to newbies, who don't appreciate the problems it will cause. – john Jul 13 '19 at 19:30
  • @john I added a rating for each solution, to help whoever need this answer choose the best way. – Coral Kashri Jul 13 '19 at 20:03