#c
#c #c
Вопрос:
Я использую два приведенных ниже файла для своего проекта. Переменная, на которую я ссылаюсь, Node parent
, изначально не была указателем, но я быстро обнаружил, что это не работает по очевидным причинам (память).
Поэтому я превратил его в указатель. Проблема в том, что parent
, похоже, она неправильно обрабатывается в моем коде, поэтому в конечном итоге мое приложение выходит из строя при выполнении функции, подобной getParent() . Какие изменения могли бы устранить эту проблему?
Node.h
#include <string>
#include <vector>
#include <iostream>
#include "Action.h"
class Node
{
Node.cpp
#include "stdafx.h"
Комментарии:
1. Для повышения производительности вам следует перейти
std::string title
наconst std::stringamp; title
2. Вам нужно научиться передавать параметры по ссылке.
3. Еще лучшая производительность
: title(std::move(title))
🙂 @EdHeal Я не думаю, что это дает преимущество в производительности, компилятор не может перемещать оптимизацию и вместо этого должен делать копию.4.
std::vector<Node> getChildren();
— Вы будете обожжены этим, если ваша цель — вернуть настоящих детей, а не их копии. Верните ссылку, если вы хотите, чтобы были возвращены фактические дочерние элементы.5. Этот код изобилует потенциальным неопределенным поведением . Пример: и
Node(std::string title, Node parent)
конструктор, иNode::setParent(Node parent)
установщик сохраняют адрес автоматической временной переменной (предоставленный параметр) в качестве значенияthis->parent
элемента. В обоих случаях в момент завершения текущей функции этот объект перестает существовать, а указатель остается висячим. Я думаю, вам нужно больше изучить время жизни объекта, указатели, ссылки и т. Д., Прежде чем браться за это. Это не так тривиально, как вы, возможно, думаете. Скорее наоборот; это утомительная работа.
Ответ №1:
Вы должны проверить, является ли parent
это nullptr
или нет:
bool Node::getParent( Nodeamp; node )
{
if ( parent )
{
node = *parent;
return true;
}
else
{
return false;
}
}
Обратите внимание, что вам необходимо реализовать надлежащий конструктор копирования Node
is.
Возможным решением является возврат указателя или ссылки на родительский узел, но в нескольких реализациях это опасно, потому что вы разрешаете доступ непосредственно к внутреннему члену. Решите, что хорошо для вас.
Просто предложение: если вы используете std::sharer_ptr или std::unique_ptr , некоторая реализация будет намного проще.
Комментарии:
1. Есть идеи, почему родительский элемент не присваивается должным образом? Я добавил конструктор копирования, который переносит все свойства. По сути, это узел с пустой строкой, без дочерних элементов, родительских элементов, действий и т. Д.
2. В методе getParent(…)? Вы уверены, что
parent
член не является nullptr ? Может быть, какой-нибудь фрагмент кода был бы полезен.3. Я думаю, что это связано с SetParent(..), а не с getParent(..), Но не уверен, что может быть причиной этого.
4.
void returntoPreviousNode() { Node *parent = currentNode.getParent(); if (parent == nullptr) { ; //Do nothing then. } else { currentNode = *currentNode.getParent(); } }
5. Например, это правильно выполнит currentNode = *currentNode.getParent(); но он всегда будет возвращать узел с пустым заголовком среди других пустых свойств
Ответ №2:
Вы должны проверить, имеет ли parent значение null или нет, прежде чем выполнять дефреференции.
преобразуйте подпись вашего getParent в:
Node* Node::getParent()
Node* Node::getParent() {
return parent;
}
И в вашем приложении всякий раз, когда вы обращаетесь к ней, сначала проверьте.
Node * parent = getParent();
if(parent==nullptr){
cout << "parent is nulln";
raise error;
}else{
// do whatever you want
}