0

SOLVED. Thaks to you all!!! :)

Im trying to create a vector that contains objects of another class but the compiler send me some errors.

this is the first class

ClassB.h

#pragma once
#include <string>
class B {
 public:
 B();
 std::string Avariable = "Hi from Class´ B member";
};

this is the socond one

ClassA.h

#pragma once
#include "ClassB.h"
#include <vector>

class A {
 public:
 A();
 std::vector <B> VectorOfB (10);
 //The c++´s book says the 10 mean 10 elements in the vector
};

main.cpp

#include <iostream>
#include "ClassA.h"

int main() {
 A *MyA;
 MyA = new A;
 //attempt to access the phrase "Hi from class´B element"
 std::cout << MyA->VectorOfB[0];
}

In this link you can find it Deitel C.7 look for page 97 lines 13 and 14.

  • You need a constructor with a *member initializer list*. [See here](https://stackoverflow.com/questions/2785612/c-what-does-the-colon-after-a-constructor-mean) and the myriad of duplicates associated therein. It will show you what to do. – WhozCraig Jun 10 '22 at 02:50
  • 1
    The compiler needs visibility of the definition of `NormalCoin` (e.g. by including a relevant header before you try to use it IN THE SAME SOURCE FILE). Some other languages will try to work things out if the compiler doesn't see relevant declarations of things your code uses - C++ is not a language which does that. More generally - read up on how to provide a MCVE (which will ensure you provide a SMALL but COMPLETE sample of code that exhibits your probem - rather than, as is the case now, requiring people to guess what you've left out). – Peter Jun 10 '22 at 02:51
  • I just edited it so it shows the headers. but I had no problems with the class Normal coin until I tryed to make the array in Game.h – TonyFR_118 Jun 10 '22 at 03:29

1 Answers1

0

Unfortunately, the compiler sees the offending line as a member declaration of the 'Game' class:

vector <NormalCoin> NormalCoins(10); // <- notice: it looks like a function!

The solution is to instead use an assignment:

vector<NormalCoin> NormalCoins = vector<NormalCoin>(10);

You may also use a brace-enclosed initializer, but as noted in the comments this may be less safe:

vector <NormalCoin> NormalCoins{10};

( see: When to use the brace-enclosed initializer? for reasons to use )

EDIT: added suggestion to initialize vector by assignment instead, and removed mention of Most Vexing Parse (thanks to user17732522 )

  • I did not try that before... and in the first instance it does not underline any errors but it does when compiling. why the line `vector NormalCoins(10);` works in Game.cpp? it also works in main.cpp – TonyFR_118 Jun 10 '22 at 03:44
  • Beware that `vector NormalCoins{10};` may not call the expected constructor since it prefers the `std::initializer_list` constructor of `std::vector`. It would probably be safer to use `vector NormalCoins = vector(10);` here. Also, this is not what the most vexing parse is. That this syntax is forbidden at class scope might be motivated by the most vexing parse and friends though. – user17732522 Jun 10 '22 at 04:21
  • @TonyFR_118 Initializing a variable inside a class with parentheses is specifically not allowed. It is allowed outside classes though. Inside classes you can use `= ...` or `{...}`, but not `(...)`, or you can use the member initializer list of a constructor as alternative, where `{...}` and `(...)` are allowed, but not `= ...`. See the duplicates I linked to the question. – user17732522 Jun 10 '22 at 04:23
  • @user17732522 Thank you, I've edited my answer to reflect your suggestion (good call to use an assignment for initialization instead). May I ask how I had misapplied the concept of MVP? I've removed its mention from my answer, but that was how I understood it – Aiman Asyraaf Jun 10 '22 at 06:18
  • @AimanAsyraaf There is no formal definition of "most vexing parse", but it is usually meant to describe a situation in which there is an ambiguity in the base language grammar where certain constructs could be interpreted as an expression or as a declaration/declarator, specified to resolve to the latter, which is usually not what the programmer intended ("vexing"). But there is no such ambiguity here. `vector NormalCoins(10);` could only be a variable declaration with `(10)` as initializer and it is just that at block scope. – user17732522 Jun 10 '22 at 06:42
  • 1
    At class scope initialization with parentheses was specifically not allowed to prevent issues with making parsing decisions when class members, declared later, are used in the initializer (see linked duplicates to this question, but this issue wouldn't apply here either since `10` is not an identifier). If OP had written `vector NormalCoins();` then it would be more in the range of what "most vexing parse" refers to, since this could be either a variable declaration or a function declaration and it would be the latter (also in a class). – user17732522 Jun 10 '22 at 06:45
  • But even then, this is not really what "most vexing parse" meant originally, see discussion [here](https://stackoverflow.com/questions/71937565/is-most-vexing-parse-a-formally-defined-concept), since `vector NormalCoins();` is just the obvious function declaration syntax that has been around since C, not something new introduced in C++. A proper example would be e.g. `int i(int(my_dbl));` in which `i` actually is a function, not a variable (example from https://en.wikipedia.org/wiki/Most_vexing_parse). – user17732522 Jun 10 '22 at 06:52
  • This link [link](https://stackoverflow.com/questions/24836526/why-c11-in-class-initializer-cannot-use-parentheses) says that these lines should work `vector myvector {12, 1}; vector myvector = vector (12, 1);` but they just dont work, those lines send me the same errors I put in the question – TonyFR_118 Jun 10 '22 at 07:52
  • 1
    @TonyFR_118 Your question doesn't have a proper [mre] and so I had to make some assumptions based on what you wrote when I closed the question (and same for the author of this answer). You need to of course `#include` before the class definition and assuming you don't have any `using namespace std;` before the class definition (which you definitively shouldn't have), it should be `std::vector`, not `vector`. Furthermore, to initialize a member at all inside a class directly you need at least C++11 (which should however be default with current compilers). – user17732522 Jun 10 '22 at 10:50
  • @TonyFR_118 If none of this fixes your issue, then please provide a proper [mre] in the question that we can copy-paste and compile to see the same error ourselves. – user17732522 Jun 10 '22 at 10:53