3

I am creating a pair1 class for a x and y Cartesian coordinate system. x and y are doubles. I need to have 3 constructors.

  1. No arguments, defaults x and y to zero.
  2. One arguement assigns x and defaults y to zero.
  3. One arugeument defaults x to zero and assigns y. I'm not sure if I am setting up the class right. I get the follwing error: pair1::pair1(double) and pair1::pair1(double) cannot be overloaded.

My class:

class pair1
{
private:
    double x;
    double y;

public:
    pair1(){ x = 0.0, y = 0.0; }    
    pair1( double a ){ x = a; y =0.0; }
    pair1(double b){ x = 0.0;  y = b; }
};
p.i.g.
  • 2,815
  • 2
  • 24
  • 41
Stephen Rogers
  • 65
  • 1
  • 3
  • 5
  • You have two ctors with the same signature. If I call pair1(3.1), which one should run? – Beta Jun 30 '11 at 01:11
  • How about using a simple `std::pair`? You could just initialize it like `x(1.2, 0)` or `x(0, 4.3)` or `x()`. That'd be way more efficient than your code (e.g. why aren't you using initializers?). – Kerrek SB Jun 30 '11 at 01:11

4 Answers4

6

1) no arguments, defaults x and y to zero.

That's easy

2) one arguement assigns x and defaults y to zero.

3) one arugeument defaults x to zero and assigns y.

That's a problem. How do you know, when you only have one parameter, which of the two is meant to be called? That's why you get a compilation error.

Instead - use the default constructor (the one with no parameters), full constructor (the one with both), if needed, and SetX() and SetY() to set the X and Y separately, and make distinction by the name of the function.

class pair1
{
    private:
    double x;
    double y;

    public:
    pair1( double a=0.0, double b=0.0 ){ x = a; y =b; };
                     // default value 0.0 allows to only
                     // set x, and leave y to be the default,
                     // or leave them both default.
    void SetX(double a) { x=a;};
    void SetY(double b) { y=b;};
};
littleadv
  • 20,100
  • 2
  • 36
  • 50
3

The problem is that the compiler has no way to distinguish

pair1(double a)

and

pair1(double b)

Indeed, they are the same thing except for the name of the parameter. For example:

pair1 myPair1(123.456); // Which constructor should be called?

This is called ambiguous overloading.

Maxpm
  • 24,113
  • 33
  • 111
  • 170
  • So would I use only one for both? I'm kind of lost right now. I have functions within the class, such as 1.assign()- assigns x and y values. 2. setx()- sets the x vaule and sety() that sets the value. would using these help? – Stephen Rogers Jun 30 '11 at 01:22
  • @Stephen Yes. The most intuitive thing to do would be to provide a default constructor that initializes both values to zero, as you have done, and provide a constructor that takes two parameters and initializes both values. – Maxpm Jun 30 '11 at 01:34
1
pair1( double a ){ x = a; y =0.0; }
pair1(double b){ x = 0.0;  y = b; }

These are exactly same constructor. Different parameter name doesn't make any difference. All that matters for overloading is, the type(s) and number of types, and their ordering.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

I'm not sure that having default arguments except for the (0,0) case is of any use, but something like this could work:

struct X
{
    double value;
    explicit X(double v) : value(v) {}
};

struct Y
{
    double value;
    explicit Y(double v) : value(v) {}
};

class pair1
{
    private:
        double x;
        double y;

    public:
        pair1() : x(0.0), y(0.0) {}
        explicit pair1(X a) : x(a.value), y(0.0) {}
        explicit pair1(Y b) : x(0.0), y(b.value) {}
        pair1(X a, Y b) : x(a.value), y(b.value) {}  // For completeness
        pair1(Y b, X a) : x(a.value), y(b.value) {}  // For super-completeness
        pair1(double a, double b) : x(a), y(b) {}
};

Use:

pair1 aPair(X(2.0));                 // default y
pair1 anotherPair(Y(4.875));         // default x
pair1 aThirdPair(X(1.0), Y(1.0));
pair1 aForthPair(Y(100.0), X(1.0));  // keyword arguments ;-)
pair1 quintus(23.0, 45.6);
molbdnilo
  • 64,751
  • 3
  • 43
  • 82