[英]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:所以我的问题是:
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?valuesOfSides
when it is not necessary to initialize?valuesOfSides
吗? In this case, only include it in the member initializer of the default constructor and not in the parameterized and copy constructor?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
.其中最重要的一项是自动内存管理,因此您不必手动调用
new
和delete
。
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.