简体   繁体   中英

object construction : default parameter vs delegation

Consider the following code where I'm trying to introduce a default constructor as well as a parameterized one for class A . This way was introduced in recent c++ improvements.

class A  {
    private:
        unsigned int count;

    public:
        A(int new_c) : count(new_c) {}
        A() : A(10) {}
};

vs the old way of setting a default parameter on parameterized constructor and ignoring the default constructor completely.

class A  {
    private:
        unsigned int count;

    public:
        A(int new_c = 5) : count(new_c) {}
};

Is there any advantage using 1st method over the 2nd one apart from following modern conventions?

Functionally there is no difference. Know that there is even another option available with non-static member initialization (since C++11):

class A  {
    private:
        unsigned int count = 10;

    public:
        A() = default;
        A(int new_c) : count(new_c) {}
};

There is no advantage in case like in your example (I'd even choose the 2nd option as more clear in such example)

Delegating constructors where added to ease work when default values were not enough.

For example

struct Point3d
{
   Point3d(int x, int y, int z);
   Point3d(Point2d p) : Point3d(p.x, p.y, 0) {}
}

Advantage will be more visible in case of larger class where can be a few constructors . In new way you will be able to write one constructor and then set it to others. This is less error prone.

class A  {
    private:
        unsigned int count;
        int other;
        float otherfloat;


    public:
        A( unsigned int count, int other, float otherfloat ) : count( count), other( other ), otherfloat( otherfloat ) {}
        A(int new_c) : A(new_c, 0, 0.0 ) {}
        A() : A(10) {}
};

While technically there is no difference, the idea behind the creation of forwarding constructors was a different one. Imagine the following class:

class sample {
    complexType member;
    bool createdWithInt;
public:
    sample() : member(5), createdWithInt(false) {
       /* code ... */
    }
    sample(int param) : sample() {
       createdWithInt = true;
       /* other code */
    }
};

So this class is hard to implement with default parameters: Its behaviour does not depend on the value of the parameter, it rather depends on the presence.

One might to try to implement it with a helper function void creator() that executes the code ... bit from the constructor without arguments. However this would mean duplicating the initialization list (or discarding the RAII principle if one initializes from within creator() ).

Note: createdWithInt could be initialized from the initialization list, if another constructor was added, that takes a bool and both current constructors forward to that one. For the sake of the example this has been omitted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM