-1

Im trying to make a very simple text game and I get really irritating error.

This line is causing me these problems -> Fleet fleet{1};

Initially I tried to write it like this -> Fleet fleet(1);

But I got this error: 'expected identifier before numeric constant'. And after some googling I found the solution ()->{} and compilator didn't display any error. After running the application I found out that it isnt working. After removing this line, everything runs how it should be. Also I was trying writing it like that: Fleet() : fleet(1) {} and then I get this error: expected unqualified-id before ')'.

I'm using C::B if thats helpful at all.

class Ship{
public:
    int max_HP;
    int HP;
    int DMG;
};

class Fleet{
public:
    int amount_of_ships;
    Ship * ship = new Ship[amount_of_ships];


    Fleet(int fleet_size)
    {
        amount_of_ships=fleet_size;
    }
};

class Player{
public:
    string name;
    Fleet fleet{1}; //this line 
};

I really dont know why it does not work. Even if I create new Fleet object in main and write the same exact line, everything works how it should be. Also I should have mentioned it earlier - I'm doing absolutely NOTHING with Player class, and with Player's fleet at the moment. Any ideas on how to fix this? :/

Kiszkacy
  • 13
  • 1

3 Answers3

1

You're consistently trying to use inline initialisers; that is, providing the initialiser for a member inside the class definition instead of with the constructor.

For your Fleet (after your syntax fix) this is fine, but your ship initialiser relies on a useful value for amount_of_ships, which is not provided until the constructor body. This happens after inline initialisers are run.

Just initialise your members in the normal manner using the ctor-initialiser, I would.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

Two things to note. Initialization of member variables proceeds in declaration order. Therefore, and according to...

int amount_of_ships;
Ship * ship = new Ship[amount_of_ships];

... ship is initialized after amount_of_ships. But here's the gotcha, you don't initialize amount_of_ships. You assign to it after initialization has run its course. And since you don't initialize it, it has an indeterminate value, the use of which causes undefined behavior.

You can use a c'tor initialization list:

Fleet(int fleet_size) : amount_of_ships{fleet_size}
{
}

Initialization will proceed in declaration order, and now amount_of_ships is indeed initialized. This may look a bit obscure to some, however.

If you are compiling C++14 and newer, then you can go full aggregate:

class Fleet{
public:
    int amount_of_ships;
    Ship * ship = new Ship[amount_of_ships];
};

This will make Fleet fleet{1}; be aggregate initialization. The amount_of_ships member is initialized directly, and ship is initialized from the default member initializer.

But your best bet would probably be not to use raw pointers at all. Don't allocate things yourself, and favor the modern C++ route. You can use std::vector:

class Fleet{
public:
    std::vector<Ship> ships;

    Fleet(int fleet_size) : ships(fleet_size)
    {
    }
};

This makes the initialization simple and implicitly correct, since the constructor for vector will do the correct thing. It also has another major benefit. Now your class has a correct d'tor, copy/move c'tors, and assignment operators. All of which you didn't have to write yourself.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • As an addendum, if you choose not to use a `vector` or similar type, you'll want to add a destructor to delete `ships`, along with (at the very least) a copy constructor & assignment operator. Probably also a move constructor & assignment operator, too. – Justin Time - Reinstate Monica Aug 18 '19 at 16:00
0

you are attempting to use a aggregated initializer list for a class that has a constructor which wont work and will result in many defined and undefined compilation errors, also you are trying to set the Fleet inside your member data on your class which will not work since its not a constexpr type, you need to simply have Fleet fleet inside your member data for class Player and then construct the fleet inside the Player constructor

Player::Player()
{
    this->fleet = Fleet::Fleet(1);
}

also this codeFleet(int fleet_size) : amount_of_ships{fleet_size} is incorrect as you are once again using aggregated initializer list where it is not needed, simply use

Fleet::Fleet(int fleet_size)
: amount_of_ships(fleet_size) \\ notice we use parentheses instead of curly brackets  
{

}

only use aggregated intializer list with structs that dont define a constructor or other special use cases which you can look up on your own,

i hope this helped.....

daniel
  • 121
  • 9