4

I've got a method that follows

class BuildOrderStrategy
{

public:

    virtual const Urgency& getUrgency() = 0;
    ...
}

which implementation follows

const Urgency& RandomBuildOrderStrategy::getUrgency()
{
    return NULL;
}

but at compile time I'm getting this error

error C2440: 'return' : cannot convert from 'int' to 'const Urgency &'

at this time I really do want to return a NULL value from getUrgency method.. so.. what is the problem with my code? how can I fix it? I came from java world where this is completely possible..

the code of Urgency is this

class Urgency : public Investment
{
private:

public:
    Urgency(BWAPI::UnitType type1, BWAPI::UpgradeType type2, BWAPI::TechType type3);
    ~Urgency(void);
};
thiagoh
  • 7,098
  • 8
  • 51
  • 77

6 Answers6

3

You are confusing references and pointers. If you return a reference, it cannot be NULL, because a reference never can. If you want to return a pointer, you need to return Urgency*, not Urgency&.

Reunanen
  • 7,921
  • 2
  • 35
  • 57
3

In C++ unlike Java and others, you can't have a null reference. Null pointers yes. But the concept of a null reference doesn't exist.

Remember that NULL is really just 0. Now stop and think for a second, does it make sense to set a RandomBuildOrderStrategy to 0?

You can use a pointer as suggested by Pukku.

daniel gratzer
  • 52,833
  • 11
  • 94
  • 134
  • so how can I return `something` that points to a null thing.. I need to return something which have the meaning of a null thing.. how can I do this? – thiagoh Nov 13 '12 at 06:01
  • You can either add the concept of `null`ness to an Urgency or you can use pointers. – daniel gratzer Nov 13 '12 at 06:02
  • sorry but how can I do this `You can either add the concept of nullness to an Urgency` – thiagoh Nov 13 '12 at 06:04
  • You could for example have a bool flag, or if it's an enum, an entry actually called null. It really depends on what Urgency is – daniel gratzer Nov 13 '12 at 06:06
  • It's not entirely clear since I'm not sure why Urgency is a type of investment – daniel gratzer Nov 13 '12 at 06:07
  • is there a way for me to go on with this signature returning references `const Urgency& getUrgency()` and return something like null when I dont find anything to return? – thiagoh Nov 13 '12 at 06:07
  • 1
    The only potential (And desperate) option I could think of would be to return NullUrgency : public Urgency. But this seems fishy to me and I would probably favor a pointer or a design change – daniel gratzer Nov 13 '12 at 06:10
3

Returning NULL from this type of function doesn't make a lot of sense. You probably want a pointer not a reference.

NULL is defined as 0 ( or even (void*)0 ) and since 0 is an integer that is what you are returning in this function which doesn't work with a reference ( which has to reference an actual object )

In this case returning a pointer to a Urgency object in your function makes more sense. So try changing the reference to a pointer.

const Urgency* RandomBuildOrderStrategy::getUrgency()
{
    return NULL;
}

Or even try returning an Urgency type that has been initialized in a special way that allowed you to check later if it is "empty".

Connor Hollis
  • 1,115
  • 1
  • 7
  • 13
  • Returning a pointer probably isn't going to improve this program in any way, though it will certainly get rid of the error. Also; *"Returning NULL from this type of function doesn't make a lot of sense"* - It doesn't make *any* sense. – Ed S. Nov 13 '12 at 06:01
  • so how can I return something when I actually dont have anything to return? for example: when I dont find any urgency, what can I return? – thiagoh Nov 13 '12 at 06:06
  • That depends on what Urgency does and how you are storing these objects. If you have a container keeping track of every allocated Urgency instance then you could just return a pointer to what you need inside that container. Another solution could be to return an "empty" (some boolean to define it as an error etc) Urgency object that you can check on the other side of your function. It's not as elegant as other solutions but it might be something you could easily implement and test quickly. – Connor Hollis Nov 13 '12 at 06:14
2

Returning NULL would be fine if your function returned a pointer. Of course, it doesn't, so it's not fine.

References are guaranteed to refer to something valid in a well behaved program (i.e., no UB). NULL would not convert to a valid reference even if there existing a conversion from int (0, NULL) to const Urgency&.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
1

You are trying to return a reference to NULL which is not allowed in C++

A reference is a name that acts as an alias, or an alternative name, for a previously defined variable.

you could change your getUrgency interface to return pointer instead. As your Urgency is inherited from Investment, you could return Investment* pointer

class BuildOrderStrategy
{

public:
    virtual const Investment* getUrgency() = 0;
    ...
}

const Urgency* RandomBuildOrderStrategy::getUrgency()
{
    return NULL;   
}
billz
  • 44,644
  • 9
  • 83
  • 100
1

The returning of a reference assures that the function doesn't return NULL but always returns a reference to an object. If you want to check for NULL you should return a pointer. OTOH if you want to return a reference, return an empty Urgency object.

AndersK
  • 35,813
  • 6
  • 60
  • 86