Simple question regarding implicit casting.

So i had an assignment in which i had to create namespace test in which i was supposed to create a class named point that represents a point in xy coordinate system (meaning that class has two attributes whose type is double), those two attributes are supposed to be public. Apart from that, i need to create a specific constructor that provides initialization of both coordinates, IMPLICIT CASTING from double to x coordinate(while y coordinate is set to zero) and initializing a point to origin.
Now, this is the header file where i created this class (i created a definition of constructor method there too for the purpose of making this question shorter even though that's not a good thing too do as far as i know).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  #include <iostream>
  
namespace test{
  
   class Point{

    public:
         double x;
         double y;
         Point (double x)
          {
              this->x=x;
               y=0;
             }
      
};


}
  


Now, i have a few questions here, as you might noticed, i wrote a part of question with uppercase letters, that's the part i don't understand, what it means that constructor must implicitly cast double to a x coordinate? Is the line where i used pointer this actually the line where implicit casting happened? Does it means that every time i assign a value to the attribute of a class object implicit casting happens? After this, there's one more question regarding this small class. Is there another way to make data members public? How can i make data members public other than declaring them after the statement public? Any help is appreciated.
The following does use both implicit and explicit casts and contains a syntax error, which will make a verbose compiler to speak about in illuminating way:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct Foo {
    int x = 0;
    Foo() = default;
    Foo( int x ) : x(x) {}
};

struct Bar {
    int x = 0;
    Bar() = default;
    explicit Bar( int x ) : x(x) {}
};

int main ()
{
  Foo gaz;
  gaz = Foo(7);
  gaz = 42;
  Bar ack;
  ack = Bar(7);
  ack = 42;
}

 In function 'int main()':
20:7: error: no match for 'operator=' (operand types are 'Bar' and 'int')
20:7: note: candidates are: 7:8: note: Bar& Bar::operator=(const Bar&)
7:8: note: no known conversion for argument 1 from 'int' to 'const Bar&'
7:8: note: Bar& Bar::operator=(Bar&&)
7:8: note: no known conversion for argument 1 from 'int' to 'Bar&&'

(Most compilers can be told to be verbose, but some are better at describing errors than others.)
Hello cdummie,

Welcome to the forum.

what it means that constructor must implicitly cast double to a x

This is backwards . In line 10 "double" is not a cast per se, but declaring the type of the variable in this case "x".

Also note that this overloaded ctor means that the compiler did not create a default ctor nor did you.
Is the line where i used pointer this actually the line where implicit casting happened?
No, in line 12 there is no casting going on. Also the use of "this->" is not necessary because the function already has access to the variables which are public. Even if they were private the function still has access to them. What you need to do different is change the variable name in the function definition, as you will see later.

Does it means that every time i assign a value to the attribute of a class object implicit casting happens?
No declaring a variable in class is just like declaring a variable in main. Once a variable is declared it will always have the same type unless you do something to change its type.

How can i make data members public other than declaring them after the statement public?
I do not know of any way make a classes "private:" member public except to put it in the public section.

The way you have written the class is kind of pointless, no pun intended, because everything is public. You could have used a struct for that. Making everything public defeats the purpose of the class.

The Class would be better used as:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>  // <--- Not needed in a header file. Also nothing that needs its use here.

namespace test
{

	class Point
	{

		public:
                        //  No default ctor made.
			Point(double a)  // <--- Overloaded ctor. Different name for the variable.
			{
				x = a;  // < ---The use of this is not needed here because this function has access to the private
						// variables. In the function definition you should a different variable name than what is
						// in the class.
				y = 0;
			}

		private:
			double x;
			double y;
	};


}


This makes better use of the class, but will require other member functions to work with the private variables.

Hope this helps,

Andy
Hello Andy,

i am not really sure what you meant, if i understood you well, implicit casting cannot happen if my class looks like that, but, how am i supposed to do that?

Note that this is an assignment i am supposed to do the way it's told and later on i am supposed to explain what's missing in class in order for it to be useful class.

So i actually have to create a single constructor that intializates both coordinates, implicitly casts double to x with y being zero and to set the point to the origin. What is the point of creating a constructor with one argument if i need to set the point to a specific, already given point, and most importantly, how can i know when implicit conversion happens if it happens without me explicitly doing it?
One constructor, called with 0, 1, or 2 arguments?

See http://en.cppreference.com/w/cpp/language/default_arguments
Hi keskiverto,

it is not specified how many arguments constructor should take.
This might not be helpful since I'm new to c++ classes too, but this is my current understanding of implicit casting if it's even correct.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <typeinfo>

class Point{
  public:
    Point(double x,double y);
    double x;
    double y;
};

Point::Point(double xx,double yy){
  x=xx;
  y=yy;
}

int main(){
  int a=6;
  float b=4.5;
  std::cout<<typeid(a).name()<<'\n'; //type i for int
  std::cout<<typeid(b).name()<<'\n'; //type f for float
  std::cout<<typeid(a*b).name()<<'\n'; //int * float implicit casts result to float
  Point p(a,b); //even though you feed an int and a float to Point constructor...
  std::cout<<p.x<<" "<<p.y<<'\n';
  std::cout<<typeid(p.x).name()<<'\n'; //they were both implicity cast to double
  std::cout<<typeid(p.y).name()<<'\n';
}
the way I read this is you want (I think the syntax is good, it should be close)

class foo
{
int x;
operator int(){return x;}
};

int main()
{
foo z;
z.x = 3;
int y = (int)z; //cast the class itself as an integer. This is usually weird (few classes boil down to a sensible atomic result), but its more useful to cast one class as another which is usually done via polymorphism but you can do it this way for some designs.
//y is 3 here.
}


consider a better example: http://en.cppreference.com/w/cpp/language/cast_operator

Last edited on
Hello cdummie,

Sorry I totally misunderstood what you were saying. Now that I understand better and have more information I will admit I am a little lost because I have not delt with this before.

I would refer to what keskiverto has said. It looks like it is more to what you need,

Sorry for misleading you,

Andy
it is not specified how many arguments constructor should take.

Isn't it?
i actually have to create a single constructor that intializates both coordinates, implicitly casts double to x with y being zero and to set the point to the origin.


Lets repeat that again:
i actually have to create a single constructor that
intializates both coordinates,
implicitly casts double to x with y being zero and to
set the point to the origin.

One function.
If it does not take at least two arguments, then it cannot initialize both coordinates (with supplied values).
Minimum of two, but there is no reason to pass more. Hence maximum of two.
Two. No less, no more.

Alas, you have to be able to call the same function with one argument and with no arguments at all. That is what the default arguments let us do.
Hi kekskiverto,

i suppose that i misunderstand meaning of the initialization,
i thought that in order to initialize coordinates i can do it even without passing arguments the following way



class Point {

int x, y;
public:
Point()
{
this->x=0;
this->y=0;

}
}



Isn't this initialization too, even though constructor had no arguments at all.
Anyway, implicit casting still remains a mystery to me.
Last edited on
Hi Andy,

no problem, it's ok. :)
Isn't this initialization too, even though constructor had no arguments at all.

Yes and no. Constructor initializes the object.

However,
1
2
3
4
5
6
Point::Point()
// this is the point where x and y are initialized
{
  this->x=0; // this is assignment to already inititalized x
  this->y=0; // this is assignment to already inititalized y
}

There is specific initializer list syntax that allows calling the constructors of members of a class:
1
2
3
4
Point::Point()
 : x(0), y(0) // this is the point where x and y are initialized
{
}



Yes, you can write:
1
2
3
4
5
6
7
class Point {
public:
  Point();
  Point( double x );
  Point( double x, double y );
  // ...
};

However, then you have to write three constructors. You yourself wrote that you "actually have to create a single constructor". The default arguments make that possible. I have given you a link that describes default arguments.


Casting is conversion. You have a value of type T, but need a value of type U. If we can create a temporary U object from the T value, then the problem is solved.

Explicit casting is ... explicit. We clearly write instruction that performs the cast.
For example:
1
2
int x = 7;
float y = static_cast<float>( x ) / 2;


Implicit cast occurs when we are not explicit, but the compiler finds a function that it can use to perform the cast.
For example:
1
2
3
4
5
void foo( Point p );

int main() {
  foo( 3.14 ); // 3.14 is a double
}

This code is valid, if compiler can create a Point from a double. It can, if Point has a constructor that can be called with one double argument, and that constructor does not have the explicit qualification.
Ok, let's see if i understood this well,

basically, since i had to create a single constructor that initializes both coordinates, and at the same time, it has to cast a double to x coordinate, and set a point to origin, this is how i should do it


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 

class Point {
      double x,y;
        
       public:

      Point (double x) //this is where implicit casting happens when i create a object Point
                             // and initialization of both coordinates
{
      x=0;         
      y=0;              // these two lines are lines where i initialized point to the origin
}

}


Is this correct?
Topic archived. No new replies allowed.