Я скопировал ваш код в Visual Studio 2017 CE и поместил его в собственный заголовочный файл. Когда я попытался скомпилировать код как есть, из вашего вопроса visual studio выдала мне ошибку компилятора:
1>------ Build started: Project: StackOverflow, Configuration: Debug Win32 ------
1>main.cpp
1>c:\users\...\container.h(41): error C2039: '{dtor}': is not a member of 'Node<V>'
1>c:\users\...\container.h(41): error C2447: '{': missing function header (old-style formal list?)
1>Done building project "StackOverflow.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Чтобы исправить эту ошибку компилятора, мне пришлось добавить declaration
вашего dtor
вdeclaration
самого класса.
template <typename V>
class Node {
//... previous code
public:
~Node();
};
Это позволило мне скомпилировать, собрать и запустить код, и я получил код выхода 0
. Мне не кажется, что в этом коде есть что-то не так с точки зрения синтаксиса или компиляции, но это не означает, что нет проблем с правильностью, эффективностью или проблемами утечек памяти, висячих указателей и т. Д. ..
РЕДАКТИРОВАТЬ
Поработав некоторое время над этим кодом, я заметил некоторые проблемы с существующим кодом:
У вас были объявлены эти два конструктора:
Node(V);
Node(V, unsigned short);
И вы определили их так:
template <typename V>
Node<V>::Node(V data)
: _data(data), _size(0), _children(new Node<V>[_size]) {}
template <typename V>
Node<V>::Node(V data, unsigned short size)
: _data(data), _size(size), _children(new Node<V>[_size]) {}
Единственная разница междудва, когда размер 0
или нет, в противном случае они, кажется, делают то же самое. В первом случае, что дает int data[0]
? Или что дает array
с 0
элементами?
Другая проблема касается использования ваших переменных-членов. Вы используете префикс _
, который плохой дизайн кода, потому что они зарезервированы для языка и компилятора или других вещей. Если вы хотите различать переменную-член и не-член. Мне нравится использовать вместо этого пост-исправление _
. Примеры: int non_member_varaible;
и int member_variable_;
.
Чтобы очистить ваш код, я удалил лишние зависимости нескольких или избыточных конструкторов. Я также держал их в объявлении класса, так как это шаблон класса. Я объявил dtor
по умолчанию. Я также удалил использование new
и delete
, используя std::vector
и std::shared_ptr
. Я также добавил некоторые вспомогательные функции для получения размера и данных. Я также ничего не делал с конструктором копирования и опускал это полностью, так как это должно быть тривиально после того, как ваш класс будет работать.
Если вы точно знаете размер массива во время компиляции, вы можете обменяться std::vector
с std::array
и немного измените код. Если вы хотите, чтобы этот класс имел единоличное владение объектами, вы можете заменить std::shared_ptr
на std::unique_ptr
с небольшими изменениями.
В демонстрационных целях я выберу std::vector<std::shared_ptr<Node>>
в качестве внутреннего контейнера.
Также вместо попытки добавить несколько узлов в конструктор;Я удалил эту зависимость и просто превратил ее в функцию, которая позволяет вам добавлять узлы во время выполнения. Если вам нужно добавить несколько узлов в этот класс, когда он создается, я бы предложил использовать variadic template constructor
. Конструктор variadic также позволит вам добавить любой тип узла в контейнер с небольшими изменениями в коде.
Вот что я придумала:
container2.h
#pragma once
#include <vector>
#include <memory>
template <typename V>
class Node {
private:
V data_;
std::vector<std::shared_ptr<Node>> children_;
public:
Node() : data_{ 0 } {}
explicit Node(V data) : data_{ data } {}
void add_node(V data) {
auto p = std::make_shared<Node<V>>(Node(data));
children_.push_back(p);
}
~Node() = default;
const size_t size() const { return children_.size(); }
const V data() const { return data_; }
// no bounds checking just for demonstration purposes.
const V data(unsigned index) { return children_[index]->data_; }
};
main.cpp
#include <iostream>
//#include "Container.h"
#include "container2.h"
int main() {
try {
Node<int> n1;
Node<char> n2('A');
Node<char> n3('B');
n3.add_node('C');
n3.add_node('E');
std::cout << n3.size() << '\n';
std::cout << n3.data(1) << '\n';
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
выход
2
E
И код выходит с кодом выхода 0
!