Graphviz отлично справляется с рисованием стрелок и автопилот. (Нетривиально реализовать в Matplotlib). Вот пример:
import networkx as nx
import matplotlib.pyplot as plt
G = nx.DiGraph()
G.add_edges_from(\[(0,1), (0,2), (1,1), (1,2)\])
nx.write_dot(G,'graph.dot')
# then run dot -Tpng graph.dot > graph.png
[/g0]
Test x = Test(1);
Это создает новый объект со значением «1».
x = Test(2);
Сначала создается новый объект со значением «2», после чего он будет присвоен первому объекту с оператором присваивания, который неявно создан для вашего класса! В этот момент у вас есть два объекта, каждый из которых имеет значение 2!
Чтобы получить лучшее представление, вы можете сделать это:
class Test{
public:
static int instanceCount;
int id;
int count;
explicit Test(int id) : id{id}, count{instanceCount++} {
std::cout << "Created " << id << " " << count << std::endl;
}
~Test() {
std::cout << "Destroyed " << id << " " << count << std::endl;
}
//Test& operator=(const Test&) = delete;
Test& operator=(const Test& ex)
{
id=ex.id;
return *this;
}
};
int Test::instanceCount = 0;
int main() {
Test x = Test{1};
x = Test{2};
std::cout << x.id << std::endl;
return 0;
}
Теперь вы можете видеть, когда новый экземпляр создано. Если вы удалите оператор присваивания для своего класса, вы увидите, что первая написанная вами инструкция «Test x = Test {1};» это не задание, а конструкция. Второй "x = Test {2};" потерпит неудачу, так как вы удалили оператора сейчас.
Вывод выглядит следующим образом:
Created 1 0
Created 2 1
Destroyed 2 1
2
Destroyed 2 0
Как видите, вы получаете первый экземпляр с счетчиком 0 и вашим значением 1. Второй временный экземпляр создается как счетчик 1 с вашим значением 2 Затем этот будет назначен первому, а временный экземпляр будет удален до того, как произойдет ваш std :: cout! В тот момент, когда вы покинете область действия основной функции, первый экземпляр будет удален!
Что вы можете узнать:
X x=X(3);
аналогично записи X x(3);
using namespace std
! X x{3} instead of
X x (3) `X x=X(3);
полностью сбивает с толку, так как похоже, что вы создаете временное и затем назначаете это по умолчанию построен один. Но этого не произойдет, и поэтому вы должны написать свой код проще! Используя отладчик, Created 2 и Destroyed 2 оба отображаются, когда строка x = Test (2); называется. Если мы просто присвоили x объекту 2, почему его деструктор вызывается немедленно? Это следует к следующей части.
blockquote>Строка
x = Test(2);
сначала создаетTest
с аргументом конструктора2
. Это то, что производитCreated 2
. Этот безымянныйTest
затем присваиваетсяx
, что даетx.id
значение 2. Этот безымянныйTest
затем уничтожается в конце выражения, создавая «Уничтожено 2».Во-вторых, поскольку был вызван деструктор для объекта 2, мы можем предположить, что он был уничтожен. Следующий вывод 2, кажется, противоречит этому, поскольку предполагает, что x все еще содержит объект 2 (ожидаемый, но противоречащий вызову его деструктора).
blockquote>Как указано в первой части этого ответа, уничтожается не
x
, а временноTemp
.x.id
все еще действует и выдаст новое значение, 2.Наконец, выводится Destroyed 2. Это имело бы смысл, если бы мы не видели это раньше. Объект 2 хранится в x, поэтому, когда он выходит из области видимости, вызывается деструктор.
blockquote>Это происходит, когда
x
уничтожается в конце функции. Это значениеid
было изменено на 2 предыдущим присваиванием, поэтому оно выдает «Уничтожено 2».1: Почему происходит это странное поведение, и есть ли логическая причина, почему это так?
blockquote>Возможно, это не то поведение, которое вы ожидали, но это не странно. Я надеюсь, что этот ответ поможет вам понять, почему это происходит.
2: приводит ли «переопределение» объекта (например, объекта 1) к другому объекту (объекту 2) посредством присваивания к его деструктору (в данном случае деструктору объекта 1) для вызова или нет? ] blockquote>
Присвоение объекту не разрушает его. Он заменяет его значение новым и в этом смысле «уничтожает» значение , которое ему ранее помогало, но фактический экземпляр объекта не уничтожается, а деструктор не участвует.
Редактировать: Возможно, вас беспокоит утечка ресурсов. Так как
Test
не управляет никакими ресурсами, утечек не будет, и сгенерированные компилятором члены будут вести себя нормально. Если ваш класс действительно управляет ресурсами (обычно в форме динамически выделяемой памяти), то вам нужно будет применить правило 3/5/0 . В частности, вам нужно будет самостоятельно реализовать оператор присваивания, чтобы он очищал любые ранее удерживаемые ресурсы. Недостаточно реализовать только деструктор, поскольку он не участвует в назначении.