explicit c++ keyword explained

A friend of mine was asking this question so quickly thought of explaining it to other doubtees. πŸ˜‰

In one sentence, it prevents automagic/implicit conversions. Let me explain with an example…

First compile this sample using the explicit keyword, compile again with explicit keyword removed. First time you will get error, second time with the explicit keyword removed there will be no errors since the compiler converts “200” to Test(200) form (magic).

[sourcecode language=’cpp’]class Test
{
public:
Test() : m_Num( 0 )
{}

explicit Test( const int Num ) : m_Num( Num )
{}

Test& operator / ( const Test& Obj )
{
m_Num /= Obj.m_Num;
return *this;
}

private:
int m_Num;
};

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
Test Obj1( 20 );
// This will cause error C2679: binary ‘/’ : no operator defined which takes
// a right-hand operand of type ‘const int’
// (or there is no acceptable conversion)
// Reason: Because the constructor that takes an int is declared as “explicit”
Test ObjResult = Obj1 / 200;
// Try this to avoid above error
// This is fine, since we are “explicit”ly creating a Test and this is the purpose
// of the explicit keyword, to prevent magic conversions
Test ObjResultProper = Obj1/Test(200);
}[/sourcecode]

explicit does help us to be in control, it’s good to use explicit when you have arithmetic operators defined, will help prevent some nasty bugs.

A constructor that takes an argument can be called a conversion operator for converting that argument type to this class’ object. πŸ™‚

3 thoughts on “explicit c++ keyword explained

  1. Take a look at this code…

    class ExpTest
    {
    public:

    explicit ExpTest( int n ) : m_n( n )
    {}

    private:
    int m_n;
    };

    int main()
    {
    ExpTest ExpObj = 1; // Will give error if explicit is defined else will compile fine since the constructor acts as a conversion operator.
    }

  2. Thanks for the explanation!

    So, if I understand correctly, explicit prevents an object being assigned from an integer (or some other data type) as if you had called the object’s constructor that took that data type as an argument?

    Meaning without explicit the line
    Object obj(100);

    would be functionally the same as
    Object obj = 100;

    Am I correct in this, or did I miss the point here?

    Thank you. God Bless!

Appreciate your comments...