У меня есть приватная переменная типа struct node (обратите внимание, что узел struct имеет левый, правый и родительский указатели, а также свойство: T value
, где T - тип шаблона) в файле заголовка:
node<T>* root
Тогда у меня есть следующий метод в файле.cpp:
template<> void RedBlack<int>::setRoot(int elem) {
root->value=elem;
}
Однако, когда я пытаюсь создать экземпляр класса в основном методе, а затем попытаюсь установить значение корня оттуда, я получаю ошибку времени выполнения: плохой доступ.
Любая идея о том, что не так? PS Еще новичок в концепции "шаблонов".
Вы выделили память для корневых точек объекта?
node<T>* root = new node<T>();
Перед тем, как он может быть использован, вам необходимо выделить объект, на который указывает указатель. Если вы этого не сделаете, он указывает на "ничего" и разыменовывает, что он будет делать плохие вещи (исключение, если оно указывает на NULL, использовать мусор, если он указывает на старый экземпляр или какой-либо другой объект и т.д.),
Кроме того, вы переменный, указатель должен "жить" где-то.
Лучшее место, вероятно, принадлежит классу, содержащему корень:
class MyClass
{
private:
node<T>* root;
public:
MyClass() // Constructor
{
root = new node<T>();
}
~MyClass() // Destructor
{
// NOTE: If root contains pointers, you need to delete the objects
// they point to as well.
delete root;
}
// Add functions to do something with root...
};
У меня есть приватная переменная типа
struct node
в файле заголовка
Нет, нет! Фактически у вас есть указатель на node<T>
. Он не указывает на действительный объект node
пока вы его не скажете. Если вы попытаетесь разыменовать указатель, который еще не указывает на действительный объект (что происходит, когда вы делаете ->
на нем), у вас есть неопределенное поведение. Вам повезло, что ваша среда дает вам хорошую ошибку. Все могло случиться.
Вам нужно будет создать node<T>
. Один из способов сделать это, если ваш класс всегда будет иметь корневой узел, состоит в том, чтобы просто сделать его node<T>
, а не node<T>*
. Тогда корневой узел является частью класса. В противном случае вы можете динамически распределить его, выполнив:
root = new node<T>();
Однако динамическое распределение не рекомендуется. Вам нужно будет запомнить delete root;
в деструкторе вашего класса, или вы можете потерять память. Это также означает предоставление пользовательского конструктора копирования и оператора присваивания для предотвращения утечек. Вместо этого, если вам нужен динамически выделенный node
, вы должны искать интеллектуальные указатели.