I am reading about implementing Rule of Three/Five, and found examples on cppreference as well as this canonical answer on SO. I know that it doesn't make sense to use a char*
in modern C++, but the point is to create some code which will need those three/five methods.
Cppreference starts with something like:
class rule_of_three
{
char* cstring;
rule_of_three(const char* s, std::size_t n) // n is passed from the public ctor
: cstring(new char[n]) // allocate
{
std::memcpy(cstring, s, n); // populate
}
public:
rule_of_three(const char* s = "")
: rule_of_three(s, std::strlen(s) + 1)
{ }
...
But the class doesn't check if s
is null
at all -- isn't this a potential problem?
I tried writing it like this:
class rule_of_three
{
char* cstring;
rule_of_three(const char* s, std::size_t n)
{
if (!s) throw std::runtime_error("s cannot be null");
cstring = new char[n]; // allocate
std::memcpy(cstring, s, n); // populate
}
but now gcc complains that
rule_of_three::cstring
should be initialized in the member initialization list [-Weffc++]
So, what would be the correct approach here?
But the class doesn't check if s is null at all -- isn't this a potential problem?
That is a problem only if null is passed to the constructor. Otherwise it is not.
the second snippet actually has a null check which prevents me from using the member init list.
Having a null check doesn't prevent you from using the member init list. Here is an example:
static char*
init(const char* s, std::size_t n))
{
if (s)
return new char[n];
else
throw std::runtime_error("s cannot be null");
}
rule_of_three(const char* s, std::size_t n)
: cstring(init(s, n))
{
So, what would be the correct approach here?
Ignoring the detail that using a bare owning pointer probably isn't a correct approach in the first place: Both checking for null and not checking for null are correct approaches. One is safer and the other is more efficient. You must choose which one is more important for your use case. Regardless, initialising members is recommended.
P.S. As dratenik points out in a comment, the public constructor relies on the pointer not being null before delegating to the private constructor, so the check in the private constructor is too late.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments