Этот вопрос закрыт для ответов, так как повторяет вопрос Почему возникает эта ошибка?
Nightmare1
@Nightmare1
Программист

Здравствуйте, почему возникает ошибка?

Вопрос из категории умных указателей.

Почему возникает ошибка

Machinery/Classes/Nodes/Node.cpp: В функции-члене «virtual void Machinery::Classes::Node::iterate_parents_to_root(std::function<void(Machinery::Classes::Node&)>)»:
Machinery/Classes/Nodes/Node.cpp:73:40: ошибка: использование удаленной функции «std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [с _Tp = Machinery::Classes::Node; _Dp = std::default_delete<Machinery::Classes::Node>]»
   73 |   auto parent = _parentable.get_parent();
      |                                        ^
In file included from /usr/include/c++/12.1.0/memory:76,
                 from Machinery/Classes/Nodes/../../Interfaces/IParentable.hpp:7,
                 from Machinery/Classes/Nodes/Node.hpp:6,
                 from Machinery/Classes/Nodes/Node.cpp:1:
/usr/include/c++/12.1.0/bits/unique_ptr.h:514:7: замечание: объявлено здесь
  514 |       unique_ptr(const unique_ptr&) = delete;
      |       ^~~~~~~~~~
Machinery/Classes/Nodes/Node.cpp:77:21: ошибка: «class std::unique_ptr<Machinery::Classes::Node, std::default_delete<Machinery::Classes::Node> >» не содержит элемента с именем «_parentable»
   77 |     parent = parent._parentable.get_parent();
      |                     ^~~~~~~~~~~


#pragma once
#ifndef __PARENTABLE_HPP_
#define __PARENTABLE_HPP_

#include "../Nameable.h"
#include "../../Interfaces/IParentable.hpp"
#include "../../Interfaces/IConnectable.hpp"
#include "../BaseGUISegmentClass.hpp"
#include <memory>
#include <utility>

#include "QuadNavigation.hpp"

#include <functional>

namespace Machinery { namespace Classes { 

using namespace Machinery::Interfaces;
using namespace Machinery::Nodes;

/**
 * @brief Класс образующий Родитель / Дочерние связи, структуру.
 */
class Node : public Machinery::Classes::Nameable, public IConnectable
{
  //ParameterGetSetTyped(std::unique_ptr<void*>, content_data);

  public:


  private:
    QuadNavigation<Node> _navigation;
        Parentable<Node> _parentable;

  public:

    Node();
    ~Node();

    /**
     * @brief Есть ли дочерние элементы объекта.
     * 
     * @return true 
     * @return false 
     */
    virtual bool haveChildNodes() const;

    /**
     * @brief Есть ли родительские элементы объекта.
     * 
     * @return true 
     * @return false 
     */
    virtual bool haveParentNodes() const;

    /**
     * @brief Есть ли следующий связанный элемент.
     * 
     * @return true 
     * @return false 
     */
    virtual bool haveNextNode() const;

    /**
     * @brief Есть ли предыдущий связанный элемент.
     * 
     * @return true 
     * @return false 
     */
    virtual bool havePrevNode() const;

    virtual bool havePrevious() const;

    /**
     * @brief Find node by it's name.
     * Поиск элемента по имени.
     * @param name 
     * @return Node<T>& 
     */
    Node * find_in_nodes_by_name(const std::string & name) const;


    //inline Node& find_in_nodes_next_one_by_name(const std::string & name) const;
    //inline Node& find_in_nodes_prev_one_by_name(const std::string & name) const;
    //inline Node& find_in_nodes_next_one_by_name_cycled(const std::string & name) const;


    virtual bool haveConnection() const override;

    virtual bool isLinked() const;

    /**
     * @brief Перебрать родительские элементы до корневого.
     * 
     */
    virtual void iterate_parents_to_root(std::function<void(Node&)> func);

}; } }

#endif // __PARENTABLE_HPP_


#include "Node.hpp"

using namespace Machinery::Classes;


Node::Node()
{

}

Node::~Node()
{
  
}


bool Node::haveChildNodes() const
{
  return false; // !_parentable.get_childrens().empty();
}


bool Node::haveParentNodes() const
{
  return false; // !_parentable.get_parents().empty();
}


bool Node::haveNextNode() const
{
  return _navigation.haveNext();
}


bool Node::havePrevNode() const
{
  return _navigation.havePrev();
}


Node* Node::find_in_nodes_by_name(const std::string & name) const
{
  for(auto &item : _parentable.get_childrens());
  //  if(item->getName().find(name) != item->getName().end()) return item;


  return nullptr;
  //if(item->getName().find(name) != item->getName().end()) return item;
}




bool Node::havePrevious() const
{
  return havePrevNode();
}


bool Node::haveConnection() const
{
  return _navigation.haveNext() || _navigation.havePrev();
}

bool Node::isLinked() const
{
  return haveConnection();
}


void Node::iterate_parents_to_root(std::function<void(Node&)> func)
{
  auto parent = _parentable.get_parent();
  while(parent)
  {
    func(*parent);
    parent = parent._parentable.get_parent();
  }
}
  • Вопрос задан
  • 77 просмотров
Ответы на вопрос 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Первая ошибка: проблема в том, что вызывается конструктор копирования unique_ptr, но он авторами unique_ptr удален (потому что unique_ptr нельзя копировать по дизайну).

Похоже get_parent возвращает ссылку на unique_ptr. По-моему тут лучше возвращать сырой указатель или ссылку на объект. зачем вам тут unique_ptr вообще?

Но, игнорируя дизайн, ссылка на unique_ptr в принципе будет работать. Проблема в том, что auto не выводит ссылочность. Поэтому переменная parent становится просто unique_ptr, который конструируется из ссылки копированием. Поэтому если вы напишите auto& parent = то все должно заработать.

Вторая ошибка - .обращается к методам и полям класса unique_ptr, ведь переменная parent имеет тип unique_ptr<>. Чтобы обратиться к методам/полям хранимого класса надо использовать ->.
Ответ написан
Ваш ответ на вопрос

Вопрос закрыт для ответов и комментариев

Потому что уже есть похожий вопрос.
Похожие вопросы