Jump to content
  • Advertisement
Sign in to follow this  
discman1028

C++ Constructor Arcane-ness :)

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, I had never seen this C++ feature before until someone mentioned it the other day:
class A;
class B;

void main()
{
   B obj("hello");  // This actually calls B::B(A::A("hello"))
}
class B
{
   B(A obj) { ... }
};
class A
{
   A(char * str) { ... }
};
This example might not be syntactically correct, but it's the idea. Anyone actually use this for something useful? (What is a use?) discman1028

Share this post


Link to post
Share on other sites
Advertisement
Probably so things like this don't generate errors:

#include <string>

int main() {
A a("example");
...
}

struct A {
A(std::string string) { ... }
...
};

Share this post


Link to post
Share on other sites
It's kind of a side effect of something else entirely.

Constructors that take a single argument and aren't marked as explicit get used for implicit type conversions. That is, due to A's constructor, the compiler now knows how to automatically turn a character pointer into an A object.

In your example, B's constructor expects and A object, but you pass a character pointer. The compiler knows how to create an A object from a character pointer, so it does the conversion for you, so it works.

It doesn't have to be a constructor; it will automatically convert types for all functions and operators if the types aren't what it expects, and there is only one possible way to do it; otherwise it will complain about ambiguity.

It is a useful feature, it can save you writing code for every possible way something might be used, or having to cast everything to the proper type. It can also be an unobvious way to lose performance, because functions are going to end up being called and objects created that isn't obvious when you look at the code.

Share this post


Link to post
Share on other sites
Thanks!

Quote:
Original post by smart_idiot
It can also be an unobvious way to lose performance, because functions are going to end up being called and objects created that isn't obvious when you look at the code.


Though, it would only be unobvious that an object is being created if the programmer used this methodology by accident. Then again, I guess they could know the feature without knowing what's going on, too.

Share this post


Link to post
Share on other sites
Quote:
Original post by bballmitch
umm...I see how that works, but I can't think of ANY situation where that would be useful. :(


How about this.

struct Point
{
Point(double x, double y)
: m_x(x), m_y(y)
{ }

double m_x;
double m_y;
}

Point origin(0, 0);


Wouldn't you be surprized if that didn't compile?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Just thought I would add how you can prevent that behaviour as it's not always desirable.


class A;
class B;

void main()
{
B obj("hello"); // Error, A::A(char*) is marked explicit
}



class B
{
B(A obj) { ... }
};



class A
{
explicit A(char * str) { ... }
};

Share this post


Link to post
Share on other sites
Quote:
Original post by Bregma
Quote:
Original post by bballmitch
umm...I see how that works, but I can't think of ANY situation where that would be useful. :(


How about this.

struct Point
{
Point(double x, double y)
: m_x(x), m_y(y)
{ }

double m_x;
double m_y;
}

Point origin(0, 0);


Wouldn't you be surprized if that didn't compile?


I would have been surprised if that compiled, since no constructor is made for type double! I did not know that was possible. I would be less surprised, in this shown case though, since I can understand implicit casting from int to double. But from a POD (plain old datatype) to an object, via a constructor, I was surprised.

By the way, I believe this property may only be "nested" a couple times (only a couple constructor levels down). I haven't tested it, it's just whaty I heard from my source.

@Anonymous Poster: Yep, that 'explicit' keyword is good to know! Thanks to the posters here for letting me know about it!

Share this post


Link to post
Share on other sites
Ah, but there is, although I don't know if it officially is a constructor. That is why the following code works.


#include <iostream>

using namespace std;

int main(void)
{
double d(4.5);
int i(3);

cout << "d = " << d << ", i = " << i << endl;
return 0;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!