A solution is to convert "Rosie"
to char*
using (char*)
, I am curious if it is another one.
CodePudding user response:
String literals in C have types of constant character arrays that used as expressions with rare exceptions are converted to pointers to their first characters of the type const char *
. But the first parameter of your constructor has the type char *
instead of const char *
. So the compiler issues an error.
Also the constructor can produce a memory leak due to the default argument where a memory is dynamically allocated but not deleted.
You could declare the constructor at least the following way
Autoturism( const char * = "", unsigned int = 0 );
As the memory is allocated dynamically you need explicitly to define the destructor that will delete the allocated memory and the copy constructor and the copy assignment operator or to define the last two as deleted.
CodePudding user response:
First, note that your default parameter value (c = new char[1]()
) is a memory leak, since the constructor doesn't take ownership of the new[]
'ed memory to delete[]
it later. There is never a good reason to use new[]
'ed memory for a parameter's default value.
"Rosie"
is a string literal. It has a type of const char[6]
, which in C 11 and later cannot be assigned as-is to a non-const char*
pointer, an explicit type-cast is required (in which case, you should use const_cast
instead of a C-style cast), eg:
#include <iostream>
#include <string>
class Autoturism
{
static int nr_autoturisme; // nr_autoturis 'active'
char* culoare;
unsigned int a_fabricatie;
public:
Autoturism(char* = nullptr, unsigned int = 0);
~Autoturism();
// TODO: you will also need a copy constructor and a
// copy assignment operator, per the Rule of 3/5/0:
// https://en.cppreference.com/w/cpp/language/rule_of_three
...
};
int Autoturism::nr_autoturisme{ 0 };
Autoturism::Autoturism(char* c, unsigned int an)
{
if (!c) c = const_cast<char*>("");
size_t len = strlen(c);
culoare = new char[len 1];
strcpy_s(culoare, len 1, c);
an_fabricatie = an;
nr_autoturism;
std::cout << "\nConstructorul a fost apelat !";
}
Autoturism::~Autoturism()
{
delete[] culoare;
std::cout << "\nDeconstructorul a fost apelat !";
}
...
int main()
{
Autoturism a1;
Autoturism a2(const_cast<char*>("Rosie"), 1999);
...
return 0;
}
Otherwise, if you really intend to stay with C-style string handling, then you should change the c
parameter to const char*
instead (it should be a pointer-to-const
anyway, since the constructor does not modify the data being pointed at), eg:
#include <iostream>
#include <string>
class Autoturism
{
static int nr_autoturisme; // nr_autoturis 'active'
char* culoare;
unsigned int a_fabricatie;
public:
Autoturism(const char* = "", unsigned int = 0);
~Autoturism();
// TODO: you will also need a copy constructor and a
// copy assignment operator, per the Rule of 3/5/0:
// https://en.cppreference.com/w/cpp/language/rule_of_three
...
};
int Autoturism::nr_autoturisme{ 0 };
Autoturism::Autoturism(const char* c, unsigned int an)
{
if (!c) c = "";
size_t len = strlen(c);
culoare = new char[len 1];
strcpy_s(culoare, len 1, c);
an_fabricatie = an;
nr_autoturism;
std::cout << "\nConstructorul a fost apelat !";
}
Autoturism::~Autoturism()
{
delete[] culoare;
std::cout << "\nDeconstructorul a fost apelat !";
}
...
int main()
{
Autoturism a1;
Autoturism a2("Rosie", 1999);
...
return 0;
}
But, with that said, why are you using this old C-style string handling in C at all? You should be using std::string
instead (you are already including the <string>
header), just let it deal with all of the memory management for you, eg:
#include <iostream>
#include <string>
class Autoturism
{
static int nr_autoturisme; // nr_autoturis 'active'
std::string culoare;
unsigned int a_fabricatie;
public:
Autoturism(const std::string & = "", unsigned int = 0);
// std:string is already compliant with the Rule of 3/5/0,
// so the compiler's auto-generated destructor, copy constructor,
// and copy assignment operator will suffice...
};
int Autoturism::nr_autoturisme{ 0 };
Autoturism::Autoturism(const std::string &c, unsigned int an)
{
culoare = c;
an_fabricatie = an;
nr_autoturism;
std::cout << "\nConstructorul a fost apelat !";
}
int main()
{
Autoturism a1;
Autoturism a2("Rosie", 1999);
...
return 0;
}