1

Take the following Seat class:

class Seat
{
    Passenger* passenger;    // I'd like this to be Passenger passenger;
}

If I remove the asterisk, how should I update the following method?

bool initSeat()
{
    passenger = NULL;             // &passenger = NULL; does not compile as it's not a reference type.
    return passenger == NULL;     // Is there even a need to allocate memory? Maybe have the method blank?
}

and

bool insertSeat(Passenger* p)
{
    bool bsuccess = TRUE;
    if (p != NULL)
    {
        if (passenger == NULL) // replace with &passenger
            passenger = p;     // replacing with &passenger doesn't compile
        else
            bsuccess = FALSE;
    }
    else
        passenger = NULL;   // again, prefixing the & doesn't compile (that'd make it a reference type) so how do I set the pointer to NULL?
    return bsuccess;
}

I might be confused because I am missing some basic concept.

Rishi
  • 945
  • 2
  • 15
  • 23
  • "Steps"? Make the change, attempt to compile, fix the errors, attempt to compile, fix the errors, attempt to compile ... – user229044 Jul 13 '14 at 05:50
  • 1
    If you remove the `*`, you will need to reset the passenger to its initial state, i.e. call its constructor. It does have a constructor, doesn't it? Otherwise, you may need less elegant means, like an extra `passengerHasBeenAssigned` flag. – Mr Lister Jul 13 '14 at 05:50
  • 1
    @meagar I'm not a fan of the "patch it until it seems to work" approach. – Mr Lister Jul 13 '14 at 05:51
  • 3
    To answer this it depends on what `Passenger` looks like. As things stand you have a state "No passenger exists" which is represented by null pointer. If you change `passenger` to not be a pointer, then you no longer have that state. Either (a) make the program not consider that NULL passenger is different to a default-constructed passenger, or (b) `Passenger` itself has to be able to represent a "there is no passenger" state, or (c) don't make this change – M.M Jul 13 '14 at 06:02
  • You probably want a `public` class as well. It's just an assumption, but probably sound. – delrocco Jul 13 '14 at 06:04
  • @MattMcNabb yup, that's exactly my concern. I think I'll go for A. – Rishi Jul 13 '14 at 06:10

3 Answers3

3

Edited version. Read my comments:

class Seat
{
    Passenger passenger; 
}

InitSeat not required since passenger would be initialized by constructor of Passenger class.

//bool initSeat()
//{
//  passenger = NULL;             
    //return passenger == NULL;    
//}

Assuming, you would be getting a pointer only as argument:

bool insertSeat(Passenger* p)
{
    bool bsuccess = TRUE;
    if (p != NULL)
    {
        passenger = *p;     // dereference the pointer directly

    }
    else {

        passenger = Passenger(); // Might not be needed, but if needed make sure the assignment operator is properly(operator=) implemented 
    }  
    return bsuccess;
}

Basically you need to brush up pointer stuff and basic class designing.

Arunmu
  • 6,837
  • 1
  • 24
  • 46
  • This what I just came up with. The assignment operator's implementation messed me up. Would it be a good idea to modify the parameter to not be a pointer as well? – Rishi Jul 13 '14 at 06:04
  • Yes, in that case you might want to make the argument take as reference (pass by reference). With that you dont have to do NULL check (may be other member level checks are required which may not be needed in your case based on the code) and you can directly do an assignment. – Arunmu Jul 13 '14 at 06:08
  • Can you elaborate on what you mean by: `make sure assignment operator is properly(operator=) implemented`? I'm familiar with operator overloading but what would I do in the overloaded method? – Rishi Jul 13 '14 at 06:14
  • 1
    You should try to avoid things like `passenger = Passenger()` though; in this case it should not be needed, unless you explicitly allow `insertSeat(NULL)` to _remove_ the passenger. – Mr Lister Jul 13 '14 at 12:43
  • 1
    @Rishi Nothing special. Just read through this link. It would be helpful. http://www.learncpp.com/cpp-tutorial/911-the-copy-constructor-and-overloading-the-assignment-operator/ – Arunmu Jul 13 '14 at 19:27
2

You should really read more on pointers to help you understand memory allocation and dereferencing. I highly recommend you read some solid C/C++ beginners tutorials before continuing.

Basically if you have a pointer, it is just a memory address. You allocate memory and assign that address to the pointer. Then you use the pointer to reference memory appropriately.

If you are converting a member from a pointer to a regular variable, you would no longer need to allocate any memory. You would also access its members with a "." versus an "->" character. But keep in mind when you pass this variable around, it is now much larger (the size of all its members), which is why passing a pointer around is much more efficient.

It looks like from your comments that you are trying to use references... which is another topic. Try this:
Difference between pointer to a reference and reference to a pointer

Community
  • 1
  • 1
delrocco
  • 495
  • 1
  • 4
  • 23
  • So for example, in `initSeat()` I would create use `Passenger = new Passenger;` to allocate the memory? – Rishi Jul 13 '14 at 05:56
  • 1
    Use a constructor instead of `initSeat`. A constructor is a method with no return type and same name of class, for example `public Seat() {}`. – delrocco Jul 13 '14 at 06:03
  • When I'm done with the variable, what do I do? If it was a pointer I would do `delete passenger;` then `passenger = NULL;` – Rishi Jul 13 '14 at 06:16
  • the first statement could become `delete *passenger;` but what of the second? – Rishi Jul 13 '14 at 06:17
  • I don't think you should be deleting anything. You don't need to delete your non-pointer member variable, and you probably shouldn't be deleting any pointers passed to your class. Whoever passed it should delete it. – delrocco Jul 13 '14 at 06:18
  • but if I was to? I'm just curious; I'll probably have the pointer deleted by the original passer. – Rishi Jul 13 '14 at 06:21
2

There is no such thing as a null object. There are many ways of emulating this behaviour though. For example, you can overload the bool conversion operator for Passenger to achieve the behaviour you want. For example,

class Passenger
{
public:
operator bool() const{return not isNull;}
void nullify() {isNull = true;}
protected:
bool isNull;
};

initSeat would now look like this:

bool initSeat()
{
    passenger.nullify();
    return !passenger;
}

bool insertSeat(Passenger p)
{
    bool bsuccess = TRUE;
    if (p)
    {
        if (!passenger)
            passenger = std::move(p);
        else
            bsuccess = FALSE;
    }
    else
        passenger.nullify();
    return bsuccess;
}

You could also try to use boost::optional.

Pradhan
  • 16,391
  • 3
  • 44
  • 59