3

So I wrote some C++ today after a long break for a simple coordinate system and I figured I'd want a constructor to take in 2 values so that I could write things like "Coordinates c = new Coordinates(1,2);"

struct Coordinates {
   int x;
   int y;

   Coordinates(int a, int b) {
      x = a;
      y = b;
   }
};

When compiled in Cygwin, I get:

$ g++ -o adventure adventure.cpp adventure.cpp:36: error: no matching function for call to `Coordinates::Coordinates()' adventure.cpp:22: note: candidates are: Coordinates::Coordinates(const Coordinates&) adventure.cpp:26: note: Coordinates::Coordinates(int, int)

Not sure what's going wrong here and I can't find much info on C++ struct constructors. Any ideas?

4
  • Can you paste the line of code that gives the error? Is it something like Coordinates c;? If so, that's not legal because you have no way to construct a Coordinates without either the two integer parameters or another Coordinates. Commented May 21, 2012 at 23:59
  • 1
    You tried to default construct the Coordinates object. Have one if you want the objects to be default constructible. Commented May 22, 2012 at 0:00
  • 1
    Coordinates c = new Coordinates(1,2); This is wrong. Should be Coordinates* c = new Coordinates(1,2); Commented May 22, 2012 at 0:01
  • 2
    However most probably it's a better idea to not use dynamic allocation at all and just write Coordinates c(1,2); Commented May 22, 2012 at 0:13

2 Answers 2

8

In line 36 of your code (which you are not showing) you are creating an object of this class but you are not passing any arguments to the constructor. The only valid constructors are one that takes two ints, or the default copy constructor. Either add a constructor w/o arguments, or change the code to pass a and b to the constructor.

Sign up to request clarification or add additional context in comments.

1 Comment

You're right. 'Coordinates currentPos;' is in global scope below the struct declaration and I was trying to initialize currentPos in an init() method called by the main function, but writing it like that would require a no-argument constructor. Thanks to Jagannath's suggestion, I realized how to keep everything straight. I changed it to 'Coordinates* currentPos;' and am correctly initializing it later.
4

By writing an explicit constructor, you disabled the automatic creation of a default constructor, which is used when defining objects without constructor parameters, as in Coordinates coords;. You have to explicitly supply it like this:

struct Coordinates {
  int x;
  int y;

  Coordinates(int a, int b) {
    x = a;
    y = b;
  }

  Coordinates(): x(0), y(0) {}
};

Note that I initialized the member variables in the default constructor; it's not mandatory, but it's a good idea because otherwise they will be undefined even in situation where they would be default-initialized with the compiler-generated construction.

Also note that I used member initializers (the : x(0), y(0) part) instead of assignments in the constructor body. That's good style, for class objects generally gives better performance, and in some cases is the only way to initialize a member at all (e.g. if it is of const type or has no default constructor).

Note that in C++11, you can just tell the compiler to generate the same default constructor which it would have generated without the other constructor, by just writing

Coordinates() = default;

in the class definition.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.