There are a few nuances left to explain, so I'll leave some comments here.
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 Car;
- Declare a variable of type Car in the local scope, usually in the stack, which will be automatically destroyed when the scope expires.
-
Car Car ();
- Declare not a variable but yes a function with no arguments, which returns an object of type Car. This is why you get the following error message:
error: request for member 'getModelo' in 'carro', which is of non-class type 'Carro().
It is now easy to see why the error.
-
Car Car ("Astra", "Chevrolet");
- Declares a variable of the type Car in the local scope, usually in the stack, that will be automatically destroyed when the scope ends. Unlike the second example, here the default constructor is not executed, but the constructor that receives two arguments.
-
Car * car = new Car; // Using pointer
- Default builder call (default boot)
-
Car * car = new Carriage (); // Using pointer
- Default builder call (value initialization)
In the last two examples the difference is with the initialization of class members, but for your particular example, there is no practical difference. The instructions allocate a memory space by calling the new()
operator and implicitly call the constructor C arro::Carro()
, with the this
pointer pointing to a space in that memory (returned by new(
). This address is then stored in the pointer carro
(stack). Because the allocated memory is not automatically freed when the scope ends, it is necessary to perform memory management manually through the delete
statement.
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 accessible default 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 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 one more of the gems of C ++ that we all love. :)