2

Hello guys i got a error when im doing this in c++.

class Position {
private:
    int posX;
    int posY;
public:
    Position(int posX, int posY) {
        this->posX = posX;
        this->posY = posY;
    }

    int getPosX() {
        return posX;
    }
    int getPosY() {
        return posY;
    }
};

class SpaceShip {
private:
    Position position;
public: 
    SpaceShip(Position position) {
         this->position = position;
    }
};

int main() {

    Position position(10, 10);
    SpaceShip spaceShip(position);
    return 0;
}    

and the error i got is this.

Doesn't exist any default constructor for the clase "Position"

What i could do to solve the problem?
And also, What is the correct form to create a object attribute for a class?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Erick Jimenez
  • 368
  • 2
  • 13

2 Answers2

6

Construction of data members and base classes is done using the member initializer-list. If a data member of class type or a base class hasn't been initialized using the initializer-list, then it is default-constructed instead. Since your class doesn't have a default-constructor, you get the error.

Inside the constructor, this->position = position is an assignment, not a constructor call. position was default-constructed before you got to this line. You need to replace it with this:

SpaceShip(Position position)
    : position(position)
{ }

This uses the member initializer-list to call the copy-constructor Position::Position(Position const&).

David G
  • 94,763
  • 41
  • 167
  • 253
1

"What i could do to solve the problem?"

You can declare/define some default constructor in your class (exactly what the error message tells you):

 Position() : posX(0), posY(0) {
 }

Also you should provide an appropriate copy constructor, and assignment operator:

 Position(const Position& rhs) : posX(rhs.posX), posY(rhs.posY) {
 }

 Position& operator=(const Position& rhs) {
      posX = rhs.posX;
      posY = rhs.posY;
      return *this;
 }

Have a look at What is The Rule of 3? please.

For something common like a Position class it's at least good style to do so, and may come handy in many other situations.


"And also, What is the correct form to create a object attribute for a class?"

As stated in the other answer the correct form is to use the member initializer list in the constructor of the SpaceShip class:

   SpaceShip(Position position)
   : position(position) { }
// ^^^^^^^^^^^^^^^^^^^^

Note:
The default constructor, copy constructor and assignment operator are supplied by the compiler automatically, unless you declare any specialized constructor.

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • Yeah, but in other languages like java i can declare a object but no initialize it. can i do it in c++? or have i by obligation create a default constructor ? – Erick Jimenez Nov 30 '14 at 23:36
  • @ErickJimenez C++ isn't java, forget about what you think you know. – πάντα ῥεῖ Nov 30 '14 at 23:38
  • The rule of 3 says that *if* you need a user defined (1) copy constructor or (2) assignment operator or (3) destructor, then you probably need all 3. This class needs none of them. – Benjamin Lindley Nov 30 '14 at 23:40
  • I think that is strange, use a default constructor just for declare a empty or null variable, i used before, but i found strange, but ok, thanks :) – Erick Jimenez Nov 30 '14 at 23:43
  • @ErickJimenez: If you don't think your class should have a default constructor, then don't give it one. See the other answer, that will solve your problem without adding any extra unwanted constructors. – Benjamin Lindley Nov 30 '14 at 23:45
  • @ErickJimenez There's nothing like _"empty or null variable"_ in c++ actually. You may use pointers, but that's probably not a good idea, and a completely different kettle of fish. – πάντα ῥεῖ Nov 30 '14 at 23:46
  • @BenjaminLindley I'd suppose for something like `Position` it would be a good idea, making it a _nice class_ in the long term. – πάντα ῥεῖ Nov 30 '14 at 23:52
  • Maybe so, that's a judgement call. But, generally speaking, the correct way to solve this problem is with a member initialization list, not adding a default constructor just to shut the compiler up. There are some classes where default construction is just not appropriate. – Benjamin Lindley Dec 01 '14 at 00:00
  • @ErickJimenez You might consider accepting the other answer, still mine provides some useful considerations IMHO. – πάντα ῥεῖ Dec 01 '14 at 00:08