简体   繁体   English

对象构造:默认参数vs委托

[英]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 . 考虑下面的代码,我试图引入默认构造函数以及class A的参数化构造函数。 This way was introduced in recent c++ improvements. 这种方式是在最近的c ++改进中引入的。

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. vs在参数化构造函数上设置默认参数并完全忽略默认构造函数的旧方法。

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): 知道甚至有另一个选项可用于非静态成员初始化(从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. 有人可能尝试使用辅助函数void creator()来实现它,该函数从构造函数执行code ...而不带参数。 However this would mean duplicating the initialization list (or discarding the RAII principle if one initializes from within creator() ). 然而,这意味着重复初始化列表(或者如果从creator()内部初始化则丢弃RAII原则)。

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. 注意: createdWithInt可以从初始化列表初始化,如果添加了另一个构造函数,则需要bool并且两个当前构造函数都转发到该构造函数。 For the sake of the example this has been omitted. 为了举例,这已被省略。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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