Type Conversion Constructors (Part 1)

C language performs implicit type conversions between standard data types.

The conversion rules are as follows:

  • When converting from a smaller type to a larger one, the process is safe and automatic.

This implies that when a smaller data type is converted into a larger one, C supports implicit conversion, which is considered safe.

int main() { short s = 'a'; // Safe conversion from smaller to larger type unsigned int ui = 1000; // 1000 is default int, small to large type conversion int i = -2000; double d = i;

cout << d << endl;

if ((ui + i) > 0) // unsigned int + int ===> unsigned int + unsigned int > 0
{
    cout << "Positive" << endl; // This will be printed
}
else
{
    cout << "Negative" << endl;
}

cout << "sizeof(s + 'b')=" << sizeof(s + 'b') << endl; // Outputs 4, short + char ===> int + int, compiler prefers int for efficiency
return 0;

}


</div>2. Revisiting Constructors
--------------------------

Constructors can accept parameters of different types.

A constructor qualifies as a conversion constructor under these conditions:

1. It accepts exact one parameter.
2. The parameter is a basic data type.
3. The parameter is of another clas type.

Traditional C-style explicit casting:

<div>```
int i;
Test t;

i = int(1.5);
t = Test(100);

class Test { private: int mValue; public: Test() { mValue = 0; }

Test(int i)
{
    mValue = i;
}

int value()
{
    return mValue;
}

Test operator + (const Test& p)
{
    Test ret(mValue + p.mValue);
    return ret;
}

};

int main() { Test t; t = 100; // Compiler attempts to make the code compile // Since 100 is an int, compiler searches for a conversion constructor, finds Test(int) // Therefore, this is equivalent to t = Test(100)

cout << t.value() << endl; // Output: 100    

Test tt;
tt = t + 10; // Is this intentional or a typo? A common source of bugs
cout << tt.value() << endl; // Output: 110


return 0;

}


</div>3. Preventing Implicit Type Conversion by the Compiler
------------------------------------------------------

In practice, use the `explicit` keyword to prevent automatic type conversions.

When a conversion constructor is marked with `explicit`, it can only be invoked explicitly.

Available conversion methods:

1. `static_cast<ClassName>(value)` – Recommended C++ approach
2. `ClassName(value)`
3. `(ClassName)value` – Not recommended

<div>```
#include <iostream>
using namespace std;

class Test
{
private:
    int mValue;
public:
    Test()
    {
        mValue = 0;
    } 

    explicit Test(int i) // explicit keyword applied
    {
        mValue = i;
    }

    int value()
    {
        return mValue;
    }

    Test operator + (const Test& p)
    {
        Test ret(mValue + p.mValue);
        return ret;
    }

};

int main()
{
    Test t;
    t = static_cast<Test>(100); // Without explicit cast, compilation would fail
    cout << t.value() << endl; // Output: 100    

    Test tt;
    tt = t + static_cast<Test>(10);
    cout << tt.value() << endl; // Output: 110

    
    return 0;
}
  • Conversion constructors take exactly one argument.
  • The argument must be of a different type.
  • These constructors are invoked during type conversion.
  • Implicit conversion are often a significant source of bugs in real-world projects.
  • The explicit keyword prevents unintended implicit conversions.

Tags: C++ Type Conversion Constructors explicit keyword implicit conversion

Posted on Sat, 11 Jul 2026 16:49:20 +0000 by nelsok