C++: Vector3 velEmtr = new Vector3(0.0, 0.0, 0.0) compiles and runs, how?

This topic is 3073 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I am working on a game with a friend and he recently checked this in:

Vector3 velEmtr = new Vector3(0.0, 0.0, 0.0);

Which to my amazement compiles and runs. I tried searching the internet for explanations but have found none. Does anyone have any insight into why this works?

I did try doing this with classes exported by libraries we are using and it did show the error I expected:

'initializing' : cannot convert from '<type> *' to '<type>'

My other question, is if that works does that memory need to be deleted?

Share on other sites
Yep that looks like a memory leak combined with a strangely designed Vector3 class.

What does Vector3's definition look like? I'm guessing it has a constructor along the lines of: Vector3( const Vector3* o ) : m_x(o->m_x) ... or a similar assignment operator?

 BTW tell your friend to get away from Java/C# ;) (j/k)

Share on other sites
Ok, yes he did just add this to the Vector3 class:

	Vector3(Vector3* initFrom)	{		x = initFrom->x;		y = initFrom->y;		z = initFrom->z;	};

So thats the problem?

Thank you very much, for some reason I didn't even consider looking in there.

Share on other sites
Quote:
 Original post by KevArnoldWhich to my amazement compiles and runs. I tried searching the internet for explanations but have found none. Does anyone have any insight into why this works?

- Implicit conversion
- Assignment operator, copy constructor and implicit/explicit constructor rules
- SFINAE and Koenig lookup

Big can of worms in general with lots of undefined or problematic spots.

Share on other sites
Now sounds like a very good time to add a leak detector to your game.

Share on other sites
Quote:
 Original post by KevArnoldSo thats the problem?
Yes. Assuming that's supposed to be a copy constructor, the correct version would be:
Vector3(const Vector3& initFrom){   x = initFrom.x;   y = initFrom.y;   z = initFrom.z;};

Share on other sites
Quote:
Original post by Evil Steve
Quote:
 Original post by KevArnoldSo thats the problem?
Yes. Assuming that's supposed to be a copy constructor, the correct version would be:
*** Source Snippet Removed ***

Even if it wasn't supposed to be a copy constructor thats better as it's easy to dereference a pointer on a function call, and would avoid shenanigans like this.

Share on other sites
Quote:
 Original post by KevArnoldOk, yes he did just add this to the Vector3 class:*** Source Snippet Removed ***So thats the problem?Thank you very much, for some reason I didn't even consider looking in there.

Tag that constructor with the explicit keyword. As a general rule, you should tag any constructor that takes 1 argument with 'explicit'. Your problem is similar to this:

int main(){  Vector3* myVector = new Vector3(2.0, 4.0, 3.0);  printf("myVector: %p", &myVector);  printVector(myVector);}void printVector(const Vector& aVector){   printf("aVector: %p", &aVector);}

Example Output:
myVector: 0x11111111aVector: 0x22222222

Why? Because the aVector can be implicitly constructed using a Vector3 pointer with the Vector3(Vector3*) constructor. You supplied the wrong type for the function, so it looks to see if it can implicitly construct the right type with the argument you gave it. Since there's a constructor not tagged 'explicit' that can do the job, it uses that.

Thus, your error is hidden and you can get weird and subtle bugs.

Share on other sites
Yeah, the explicit keyword would certainly be beneficial here =)

Seemingly little-known feature of C++ as well, haven't met many folks that know about it.

Share on other sites
It's used all the time although you mightn't notice it:

std::string s = "Hello World";

Wouldn't be possible with an explicit constructor. You'd need to use

std::string s("Hello World");

1. 1
2. 2
Rutin
16
3. 3
4. 4
5. 5

• 26
• 11
• 9
• 9
• 11
• Forum Statistics

• Total Topics
633708
• Total Posts
3013468
×