Question

I have a constructor that accepts an object of type Material:

SomeClass::SomeClass( const Material& mat ) ;

However, Material allows construction by a Vector:

Material::Material( const Vector& v ) ;

Therefore, SomeClass can allow construction by a Vector:

SomeClass m( vec ) ; // valid, since vec is constructed to a Material first,
// then is passed to the SomeClass(Material) ctor

However, after "shooting myself in the foot" more than once with ctors of this type (in different classes in the same project!) I want to disallow construction of SomeClass by Vector objects directly, instead always requiring a Material to be passed instead.

Is there a way to do this? Somehow think it has to do with the explicit keyword.

Was it helpful?

Solution

You cannot do this without interfering with your ability to transparently construct Material from Vector.

If you make Material's constructor explicit

explicit Material( const Vector& v ) ;

then you will always have to write Material(v) in order to construct an instance. This will prevent you from instantiating SomeClass with a Vector accidentally, but it will also break all expressions that evaluate to a Vector where a Material is expected.

This makes sense, because by not declaring the constructor explicit you are saying "a Vector is just as good as a Material no matter what the context". You cannot then do a half-step backward and say "oh, well, except when constructing a SomeClass".

OTHER TIPS

You declare Material(const Vector &v) to be explicit; this prevents implicit conversion from one to the other.

This, of course, is not a specific restriction on SomeClass; it's a global ban on any instance of an implicit conversion.

Make the constructor of Material explicit:

explicit Material(const Vector& v) { ... }

Or if you don't want to do that, as a bit of a hack and with const-correctness as a sacrifice, remove the const from const Material& mat. You won't be able to pass a temporary object to the constructor for SomeClass (or a const instance which may be too big a sacrifice). However, that keeps you from doing SomeClass(Material(v)) which you may want to do. So you can only get close to what you want, but I'm afraid that it's not completely possible.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top