There are some minor nuances left to explain, so I leave here some comments.
For your example
using namespace std;
class Carro
{
private:
string modelo;
string marca;
public:
Carro(){}
Carro(string x, string y) { modelo = x; marca = y;}
}
Car car = new car;
- This statement is invalid/syntax is not valid in C++
Car;
- Declares a Car type variable in the local scope (Scope), usually in the stack, which will be automatically destroyed when the scope (Scope) ends.
Car();
- Declares not a variable but yes a function no arguments, which returns an object of type Car. This is the reason why you get the following error message:
error: request for member 'getModelo' in 'carro', which is of non-class type 'Carro().
It’s easy now to understand why the mistake.
Car car("Astra", "Chevrolet");
- Declares a Car type variable in the local scope (Scope), usually in the stack, which will be automatically destroyed when the scope (Scope) ends. Unlike the second example, the default constructor will not be executed here, but the constructor that takes two arguments.
Car *car = new car; // Using pointer
- Default constructor call (default startup)
Car *car = new car(); // Using pointer
- Default constructor call (value initialization)
In the last two examples the difference is related to the initialization of the members of the class, but for your example in particular, there is no practical difference. Instructions allocate a memory space by calling the operator new()
and implicitly call the constructor Carro::Carro()
, with the sharpener this
pointing to a space in that memory (returned by new(
)). This address is then stored in the pointer carro
(stack). Since the allocated memory is not automatically released when the scope ends, it is necessary to perform the memory management manually through the instruction delete
.
If you want to read more about the difference between
Carro *carro = new Carro; // Usando ponteiro
Carro *carro = new Carro(); // Usando ponteiro
You can read the language standard itself:
To zero-initialize an Object of type T Means:
- if T is a scalar type (3.9), the Object is set to the value of 0 (zero) converted to T;
- if T is a non-union class type, each Nonstatic data Member and each base-class subobject is zero-initialized;
- if T is a Union type, the Object’s first named data Member is zero-initialized;
- if T is an array type, each element is zero-initialized;
- if T is a Reference type, no initialization is performed.
To default-initialize an Object of type T Means:
- if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is Ill-Formed if T has no default accessible constructor);
- if T is an array type, each element is default-initialized;
- otherwise, the Object is zero-initialized.
To value-initialize an Object of type T Means:
- if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is Ill-Formed if T has no accessible default constructor);
- if T is a non-union class type without a user-declared constructor, then Every non-static data Member and base-class Component of T is value-initialized;
- if T is an array type, then each element is value-initialized;
- otherwise, the Object is zero-initialized
A program that calls for default-initialization or value-initialization of an Entity of Reference type is Ill-Formed. If T is a cv-Qualified type, the cv-unqualified version of T is used for These Definitions of zero-initialization, default-initialization, and value-initialization.
This is another of the C++ gems that we all love. :)
In the case of the third,
Carro carro()
, when I call some method, when compiling I get the following error:error: request for member 'getModelo' in 'carro', which is of non-class type 'Carro()
. That would have something to do with the stack?– André Sanches
You could, but there’s no way I could know since this method doesn’t exist in the class you showed. But as the mistake is another I imagine who added it later. So yes, there are situations that the class in stack may not function as expected.
– Maniero
I found the reason for this error. In fact, what happens in this case is that the compiler interprets
carro()
as another type of constructor, and not as the default constructor (the default constructor starts with uppercase). The compiler will interpret as default constructor only if the parentheses are omitted, which is the case for the second option (Carro carro;
). I found the solution here: http://stackoverflow.com/questions/877523/error-request-for-member-in-which-is-of-non-class-type– André Sanches
Yeah, there’s that too, but you were talking about things that aren’t even present in what you posted. This is not the case for the former because she is trying to allocate heap, not happening is confusion. But the first one is wrong because it is trying to play a pointer as class value.
– Maniero