所以我有一个班级,我们称之为牛。这头牛有一个年龄和一些其他变量,如静态数量的Cows活变量。
我想创建一个链表,我为它创建了类,并且在linkedlist类中创建了节点结构,看起来有点像这样。
struct node{
Cow data;
node* next;
};
然后我的addNode函数添加节点。
void List::addNode(Cow newData)
{
//Creates a Cow object that will skew counters. BELOW.
node* n = new node;
n->data = newData;
n->next = NULL;
if(head == NULL){
head = n;
}else{
curr = head;
while(curr->next != NULL){
curr = curr->next;
}
curr->next = n;
}
}
随着这条线 node * n = new node,它将创建一个新的Cow对象,该对象调用Cow构造函数,该构造函数增加了Cows活动静态变量的数量。
简单地说,我的问题是...... 在首次创建节点时,我将如何不调用该Cow对象的构造函数,因此我可以用newData对象填充它。因此,不要弄乱我的计数器,它在构造函数中递增?
答案 0 :(得分:2)
您可以创建一个node
构造函数,该构造函数接受Cow
参数并使用它来复制构造其内部Cow
。我假设Cow
的复制构造函数不会增加静态计数器。
struct node{
node(Cow &cow): data(cow) {}
Cow data;
node* next;
};
答案 1 :(得分:0)
您可能需要将对象移动到列表中。这样,你就不会有更多的“活着”。对象不是必需的。
您可以通过将Cow
与Node
分隔开来,以最简单的方式完成此操作。将其包裹在std::unique_ptr<Cow>
内。你可以免费获得所有正确性。
另一种方法是只允许将奶牛移动到您的列表中:
List::addNode(Cow &&cow) {
auto node = new node(std::move(cow));
...
}
但是,您还需要向Cow
添加移动构造函数,这显然不会增加计数器:
Cow::Cow(Cow &&other)
: field1(std::move(other.field1))
, field2(std::move(other.field2))
{ // dont increment counter!
other.dontDecrementCounterOnDestruction(); // important!
}
另一种可能性是实际上“安抚”&#39;你的奶牛在列表上(如std::emplace_back()
):
template<typename T...>
void List::addNode(T... arguments) {
auto n = new node(arguments...);
...
};
template<typename T...>
node::node(T... arguments): myCow(arguments...)
{ // ... whatever else needs to be done
}
但是,您非常接近std::list
所做的事情,除非它是一个练习,否则您最好只使用{无论如何{1}}或std::list
。
答案 2 :(得分:-1)
如何在首次创建节点时不调用该Cow对象的构造函数,
你做不到。构造node
对象时,将初始化其所有成员变量。 node
的定义方式如果Cow
具有默认构造函数,则会调用它来初始化data
。
所以我可以用
newData
对象填充它。
您可以做的最好的事情是使用移动构造函数或复制构造函数来避免构造成本,然后进行赋值。
将node
更新为:
struct node{
node() : data(), next(nullptr) {}
node(Cow const& copy) : data(copy), next(nullptr) {}
Cow data;
node* next;
};
然后将addNode
更新为:
void List::addNode(Cow newData)
{
node* n = new node(newData);
if(head == NULL){
head = n;
}else{
curr = head;
while(curr->next != NULL){
curr = curr->next;
}
curr->next = n;
}
}