C++ r首选的方式可能是我将要实现的。最后一个问题:如果你有一个对象tt1,我如何复制任意类T?@ThijsRiezebeek,然后语句t2(t1)和t2=t1创建一个对象t2,它是t1的副本。要使其工作,类型必须是可复制构造的(大多数类型都是可复制的)。如果您

C++ r首选的方式可能是我将要实现的。最后一个问题:如果你有一个对象tt1,我如何复制任意类T?@ThijsRiezebeek,然后语句t2(t1)和t2=t1创建一个对象t2,它是t1的副本。要使其工作,类型必须是可复制构造的(大多数类型都是可复制的)。如果您,c++,unit-testing,googletest,C++,Unit Testing,Googletest,r首选的方式可能是我将要实现的。最后一个问题:如果你有一个对象tt1,我如何复制任意类T?@ThijsRiezebeek,然后语句t2(t1)和t2=t1创建一个对象t2,它是t1的副本。要使其工作,类型必须是可复制构造的(大多数类型都是可复制的)。如果您不熟悉这个主题,我建议您阅读一些有关复制构造函数的书籍。 class StubClass { public: int data; StubClass(int _data) { data = _data; } Stub


r首选的方式可能是我将要实现的。最后一个问题:如果你有一个对象
tt1,我如何复制任意类
T
?@ThijsRiezebeek,然后语句
t2(t1)
t2=t1创建一个对象
t2
,它是
t1
的副本。要使其工作,类型必须是可复制构造的(大多数类型都是可复制的)。如果您不熟悉这个主题,我建议您阅读一些有关复制构造函数的书籍。
class StubClass {
public:
  int data;

  StubClass(int _data) {
    data = _data;
  }

  StubClass() {
    data = -1;
  }
};
class DoublyLinkedListTest : public ::testing::Test {
public:
  DoublyLinkedList<StubClass> doublyLinkedList;
};
TEST_F(DoublyLinkedListTest, LargePushAndPopRoutineWithSmartInitializedData) {
  int repetitions = 12;
  for (int i = 0; i < repetitions; i++) {
    StubClass stub(i);
    doublyLinkedList.push_back(&stub);
  }

  for (int i = 0; i < repetitions; i++) {
    ASSERT_EQ(i, doublyLinkedList.pop_front()->data);
  }
}
Value of: doublyLinkedList.pop_front()->data
  Actual: 11
Expected: i
Which is: 0
TEST_F(DoublyLinkedListTest, LargePushAndPopRoutine) {
  int repetitions = 12;
  for (int i = 0; i < repetitions; i++) {
    doublyLinkedList.push_back(new StubClass(i));
  }

  for (int i = 0; i < repetitions; i++) {
    ASSERT_EQ(i, doublyLinkedList.pop_front()->data);
  }
}
#ifndef PROJECT_DOUBLYLINKEDLIST_H
#define PROJECT_DOUBLYLINKEDLIST_H

#include "DoublyLinkedNode.h"

template<class T>
class DoublyLinkedList {
private:
  DoublyLinkedNode<T> *head = nullptr;
  DoublyLinkedNode<T> *tail = nullptr;

public:
  bool hasOneItem() {
    return head == tail && !isEmpty();
  }

  void push_front(T* data) {
    DoublyLinkedNode <T> *newNode = new DoublyLinkedNode<T>();
    newNode->data = data;

    if (isEmpty()) {
      head = newNode;
      tail = newNode;
    }
    else {
      newNode->setNext(head);
      head = newNode;
    }
  }

  void push_back(T* data) {
    DoublyLinkedNode <T> *newNode = new DoublyLinkedNode<T>();
    newNode->data = data;

    if (isEmpty()) {
      head = newNode;
      tail = newNode;
    }
    else {
      newNode->setPrev(tail);
      tail = newNode;
    }
  }

  T* pop_front() {
    if (isEmpty()) {
      return nullptr;
    }

    DoublyLinkedNode<T> *oldHead = head;
    if (hasOneItem()) {
      head = nullptr;
      tail = nullptr;

      return oldHead->data;
    }

    head->next->prev = nullptr;
    head = head->next;

    return oldHead->data;
  }

  T* pop_back() {
    if (isEmpty()) {
      return nullptr;
    }

    DoublyLinkedNode<T> *oldTail = tail;
    if (hasOneItem()) {
      head = nullptr;
      tail = nullptr;

      return oldTail->data;
    }

    tail->prev->next = nullptr;
    tail = tail->prev;

    return oldTail->data;
  }

  bool isEmpty() {
    return !head && !tail;
  }
};

#endif //PROJECT_DOUBLYLINKEDLIST_H
#ifndef PROJECT_DOUBLYLINKEDNODE_H
#define PROJECT_DOUBLYLINKEDNODE_H

template<class T>
class DoublyLinkedNode {
public:
  DoublyLinkedNode *prev = nullptr;
  DoublyLinkedNode *next = nullptr;
  T *data = nullptr;

  /**
   * Will also set 'prev' on the nextNode
   */
  void setNext(DoublyLinkedNode *nextNode) {
    next = nextNode;

    if (nextNode) {
      nextNode->prev = this;
    }
  }

  void setPrev(DoublyLinkedNode *prevNode) {
    prevNode->setNext(this);
  }
};

#endif //PROJECT_DOUBLYLINKEDNODE_H