Abstract class 'CLASSNAME' has a copy/move constructor that is not explicit.
For abstract classes, even copy/move constructors may be declared explicit,
as, by definition, abstract classes cannot be instantiated, and so objects of
such type should never be passed by value.
Could you please give an example of the problem which is solved by
adding "explicit" as suggested by noExplicitCopyMoveConstructor?
This message suggests fixes like this:
class Abstract {
public:
virtual void f() = 0;
- Abstract(Abstract const&);
+ explicit Abstract(Abstract const&);
}
But I can't see any improvement by this change.
The message seems saying that the "explicit" avoids accidental pass by
value of an abstract class. But declaring a parameter with abstract class
is an error by itself, regardless the explicit-ness of its copy/move
constructor.
$ cat test.cpp
struct Abstract { virtual void f() = 0; };
void x(Abstract a);
$ g++ test.cpp -fsyntax-only
test.cpp:2:17: error: cannot declare parameter 'a' to be of abstract type 'Abstract'
void x(Abstract a);
^
test.cpp:1:8: note: because the following virtual functions are pure within 'Abstract':
struct Abstract { virtual void f() = 0; };
^
test.cpp:1:32: note: virtual void Abstract::f()
struct Abstract { virtual void f() = 0; };
^
If no user-defined copy constructors are provided for a class type
(struct, class, or union), the compiler will always declare a copy
constructor as a non-explicit inline public member of its class.
Then, if non-explicit copy/move constructor is really dangerous, I think
it is odd that the error is produced only for user declared case.
--
k_satoda
Last edit: Kazutoshi Satoda 2015-11-05
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
EDIT
Sorry for the duplicate post.
Please use the second one, as it is more well formatted.
https://github.com/danmar/cppcheck/blob/a5f577d179e09e436b544bcbbb6b798a47f6c8b6/lib/checkclass.cpp#L778
Could you please give an example of the problem which is solved by
adding "explicit" as suggested by noExplicitCopyMoveConstructor?
This message suggests fixes like this:
class Abstract {
public:
virtual void f() = 0;
- Abstract(Abstract const&);
+ explicit Abstract(Abstract const&);
}
But I can't see any improvement by this change.
The message seems saying that the "explicit" avoids accidental pass by
value of an abstract class. But declaring a parameter with abstract class
is an error by itself, regardless the explicit-ness of its copy/move
constructor.
$ cat test.cpp
struct Abstract { virtual void f() = 0; };
void x(Abstract a);
$ g++ test.cpp -fsyntax-only
test.cpp:2:17: error: cannot declare parameter 'a' to be of abstract type 'Abstract'
void x(Abstract a);
^
test.cpp:1:8: note: because the following virtual functions are pure within 'Abstract':
struct Abstract { virtual void f() = 0; };
^
test.cpp:1:32: note: virtual void Abstract::f()
struct Abstract { virtual void f() = 0; };
^
Moreover, non-explicit copy/move constructor is implicitly declared if
not declared by user.
http://en.cppreference.com/w/cpp/language/copy_constructor
--
k_satoda
Last edit: Kazutoshi Satoda 2015-11-05