Sunday, May 1, 2011

Pet hate #843 : C++'s assignment construction

A well known c++ feature is using the assignment operator for construction. Let's work with this minimal class:

struct Integer {
    Integer(int v) : value(v) {
        std::cout << "in constructor" << std::endl;
    }

    void operator=(int v) {
        value = v;
        std::cout << "in assignment operator" << std::endl;
    }

    int value;
};

You are able to construct it using the assignment operator
Integer i = 44;

which calls the constructor, as desired. However, here I present the case for not using this "feature" and instead preferring the explicit constructor call:
Integer i(44);

Consistency

Constructor syntax must be used when there's two or more arguements e.g.
Complex c(23, 43);


The assignment construction is a feature that can only be used when there's exactly one arguement. With there already being a special case for default constructors (constructors with no arguments) let's not make it more confusing. For brevity the default constructor special case:
Singleton s;
cannot be substituted for
Singleton s();
as the latter is interpretted as forward declaring a function 's' that returns a 'Singleton'.


Clarity

Assignment and construction are two different operations, with different functions/code-paths. So be obvious as to what you're doing. e.g.


int main(int argc, char ** argv)
{
    start:
    Integer f = 34;
    if (argc-- >= 0)
        goto start;
    return 0;
}
Now while I'm sure you all can figure out if subsequent calls use the constructor or assignment operator -- but it's not obvious! Be obvious. [Note: this still point still applies when using loops and stuff. I'm just using goto's to throw a curve ball, like most code not written by you will do.]


Compatability

If the constructor is ever changed to be marked "explicit" (to prevent accidental conversion or what not) then you're code using assignment construction breaks. Which is a pain for everyone, the person who's code loses source compatibility and the person who has to jump through hurdles cause he wants to make a trivial change.


Legacy

<unsubstantiated>The only reason this feature even exists is to provide C compatability. e.g. int x = 82; makes perfect sense, as in c there is no constructors! Just reserving space and assignment to it. i.e. in C
type var;
var = value;

is identical to:
type var = value;
but this does not hold in c++
</unsubstantiated>




TODO: When i get the time, include some info about using assignment construction wrt constants