简体   繁体   English

复制构造函数的成员初始化器不需要成员

[英]Copy constructor's member initializer not requiring a member

This is my class:这是我的 class:
(I know currently it violates the rule of three because it doesn't yet have an explicitly defined copy assignment operator.) (我现在知道它违反了三规则,因为它还没有明确定义的复制赋值运算符。)

#include <iostream>

template <class T>
class die
{
private:
    int sideCount;
    T* valueOfSides;
public:
    die() : sideCount(0), valueOfSides(nullptr) {}
    die(int sideCount, T* valueOfSides) : sideCount(sideCount), valueOfSides(nullptr)
    {
        this->valueOfSides = new T[sideCount];

        for (int i = 0; i < sideCount; ++i)
            this->valueOfSides[i] = valueOfSides[i];
    }

    die(const die& that) : sideCount(that.sideCount), valueOfSides(nullptr) //<- WARNING
    {
        valueOfSides = new T[sideCount];

        for (int i = 0; i < sideCount; ++i)
            valueOfSides[i] = that.valueOfSides[i];
    }

    void printValueOfSides() //Unrelated but I will leave this method here if you decide to use it
    {
        for (int i = 0; i < sideCount; ++i)
            std::cout << "valuesOfSides[" << i << "] = " << valueOfSides[i] << std::endl;
    }

    ~die() { delete[] valueOfSides; }
};

The warning at the copy constructor's initializer list is:复制构造函数的初始化列表中的警告是:
die(const die& that): sideCount(that.sideCount), valueOfSides(nullptr)<-here The value (I'm guessing nullptr ) is never used. die(const die& that): sideCount(that.sideCount), valueOfSides(nullptr)<-here该值(我猜是nullptr从未使用过。 When I remove valueOfSides(nullptr) from the copy constructor's initializer list the warning goes away.当我从复制构造函数的初始值设定项列表中删除valueOfSides(nullptr)时,警告消失了。 I know code works without it but for the sake of completion when a die object is created using the copy constructor我知道代码在没有它的情况下可以工作,但是为了完成使用复制构造函数创建一个 die object

int main()
{
    die<int> d1(4, array);
    die<int> d2(d1);

    return 0;
}

I want it first to be initialized with the nullptr then assigned to the values in the constructor's parameter.我希望它首先用nullptr初始化,然后分配给构造函数参数中的值。 As its being done with the parameterized constructor.由于它是通过参数化构造函数完成的。
So my questions are:所以我的问题是:

  • Why do I get this warning In the copy constructor but not In the parameterized constructor ?为什么我在复制构造函数中而不是在参数化构造函数中收到此警告?
  • I include valueOfSides pointer in the member initializer of all the constructors for the sake of completion and because I believe it is good practice to initialize the members even though they will get assigned in the body of the constructor.为了完成,我在所有构造函数的成员初始化程序中包含valueOfSides指针,因为我相信初始化成员是一种好习惯,即使它们将在构造函数的主体中分配 Is this a good practice or a habit?这是一种好习惯还是一种习惯? Or should I just give up Initializing valuesOfSides when it is not necessary to initialize?或者我应该在不需要初始化时放弃 Initializing valuesOfSides吗? In this case, only include it in the member initializer of the default constructor and not in the parameterized and copy constructor?在这种情况下,只将它包含在默认构造函数的成员初始化器中,而不包含在参数化和复制构造函数中?
  • For my second question, Am I accurate with my depictions of initialization and assignment of members ?对于我的第二个问题,我对初始化成员分配的描述是否准确?
  • Update: I tried the same code on visual studio 2019 0 warnings 0 errors.更新:我在 Visual Studio 2019 0 警告 0 错误上尝试了相同的代码。 It might be IDE related, I originally got this warning using cLion(mingW compiler)可能与 IDE 相关,我最初使用 cLion(mingW 编译器)收到此警告

Regarding the warning:关于警告:
As you can see in @FrançoisAndrieux's comment (and other comments), compiler warning are not necessarity issued for things that are wrong, but rather to any piece of code that seems suspicous.正如您在@FrançoisAndrieux 的评论(和其他评论)中看到的那样,编译器警告不是针对错误的事情发出的,而是针对任何看起来可疑的代码。 Your compiler determined the initialization to nullptr is superfluous and gave you a legitimate warning.您的编译器确定对nullptr的初始化是多余的,并给了您一个合法的警告。 You can chooce whether to remove this initialization.您可以选择是否删除此初始化。

However:然而:
In C++ it is recomeded not to use old C style arrays.在 C++ 中,建议不要使用旧的 C 样式数组。
Instead you can use either std::array for a fixed size array, or std::vector for a dynamic size one (like in your case).相反,您可以将std::array用于固定大小的数组,或者将std::vector用于动态大小的数组(如您的情况)。

Using std::vector offers a lot of advantages.使用std::vector提供了很多优势。 One of the most important is automatic memory management, so you don't have to manually call new and delete .其中最重要的一项是自动内存管理,因此您不必手动调用newdelete
Also the constructors and assignment operators of std::vector will allow you to shift from the rule of five to the rule of zero ( The rule of three/five/zero ).此外, std::vector的构造函数和赋值运算符将允许您从五规则转移到规则(三/五/零规则)。

This is how your code above will look like using std::vector :这就是您上面的代码使用std::vector的样子:

#include <iostream>
#include <vector>

template <class T>
class die
{
private:
    std::vector<T> m_valueOfSides;
public:
    die() = default;
    die(std::vector<T> const & valueOfSides) : m_valueOfSides(valueOfSides) {}

    void printValueOfSides() //Unrelated but I will leave this method here if you decide to use it
    {
        for (int i = 0; i < sideCount; ++i)
            std::cout << "valuesOfSides[" << i << "] = " << valueOfSides[i] << std::endl;
    }

    // NOTE: copy ctor and the rest from the rule of five are not needed.
};

int main()
{
    std::vector<int> arr{ 1,2,3,4 };
    die<int> d1(arr);
    die<int> d2(d1);
    return 0;
}

As you can see it became a lot shorter, and less error-prone.如您所见,它变得更短,更不容易出错。

There are two different things named valueOfSides , one is your class member and one is the constructor parameter.两个名为valueOfSides的东西,一个是您的 class 成员,一个是构造函数参数。 The class member is initialised with nullptr and the parameter is never used. class 成员使用nullptr初始化,并且从不使用该参数。 That's what the warning says.这就是警告所说的。

To remedy, either remove the unused parameter name要进行补救,请删除未使用的参数名称

die(int sideCount, T*) : ...

or remove the parameter altogether或完全删除参数

die(int sideCount) : ...

whichever suits you more.哪个更适合你。

Of course you should never ever use raw pointers and new and (the worst of all) new[] in modern C++, unless specifically required by some kind of unstoppable force.当然,你永远不应该在现代 C++ 中使用原始指针和new和(最糟糕的) new[] ,除非某种不可阻挡的力量特别要求。 But this is a different story.但这是一个不同的故事。

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

相关问题 C ++ auto with member initializer syntax and deleted copy constructor - C++ auto with member initializer syntax and deleted copy constructor 在构造函数初始化器中初始化成员数组 - Initializing a member array in constructor initializer 成员函数和副本构造函数 - member functions and the copy constructor constexpr 构造函数需要常量成员 function 的问题 - problem with constexpr constructor requiring constant member function 在类定义中使用删除的副本构造函数和初始化程序列表重载调用成员构造函数 - Calling a member constructor in class definition with a deleted copy constructor and initializer list overload 具有成员初始化程序列表的C ++结构构造函数 - C++ struct constructor with member initializer list 在构造函数初始值设定项中使用成员的成员函数 - Using member functions of members in the constructor initializer 构造函数初始化列表中的非成员初始化 - Non-member initialization in constructor initializer list 成员初始值设定项列表中自定义对象数组的构造函数 - Constructor for array of custom objects in member initializer list 构造函数干扰成员变量指定的初始化程序? - Constructor interferes with member variable designated initializer?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM