• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Konstruktor przenoszacy

VPS Starter Arubacloud
0 głosów
178 wizyt
pytanie zadane 23 lipca 2020 w C i C++ przez RufinB Obywatel (1,830 p.)

Konstruktor przenoszący 295-300 implementacja, 

38 specyfikacja. Konstruktor przenoszący nie działa operator przypisania przenoszącego działa poprawnie. Proszę o pomoc

//plik tree.hpp
#ifndef TREE_HPP
#define TREE_HPP
#include <iostream>
#include <map>
#include <algorithm>
#include <queue>

template <class T>
class Tree
{
	struct Element
	{
		T value;
		struct Element *left;
		struct Element *right;
	};
	void przejscie_poprzeczne(Element *&) const;
	void przejscie_wzdluzne(Element *&) const;
	void przejscie_wsteczne(Element *&) const;
	void insertElement(Element *&, Element *&);
	void clear(Element *&);
	void deleteSearch(Element *&, T);
	void deleteElement(Element *&);
	void countNodeLeaves(int &, Element *&);
	void countNodeNode(int &, Element *&);
	void heightTree(Element *&, int &, int = 0);
	void widthTree(int, std::map<int, int> &, Element *&);
	void add(Element *&, Element *&);
	 void queue(std::queue<T>&,Element*&);

  public:
	Element *root;
	Tree() : root(nullptr)
	{
	}

	Tree(Tree &);
	Tree(Tree&&);////////////////////

	~Tree()
	{
		clear(root);
	}
	void showPP()
	{
		przejscie_poprzeczne(root);
	}
	void showPWZ()
	{
		prejscie_wzdluzne(root);
	}
	void showPWS()
	{
		przejscie_Wsteczne(root);
	}
	void insert(T);
	void clearAll()
	{
		clear(root);
		root = nullptr;
	}
	bool search(T);
	void remove(T temp)
	{
		deleteSearch(root, temp);
	}
	int countLeaves()
	{
		int temp = 0;
		countNodeLeaves(temp, root);
		return temp;
	}
	int countNode()
	{
		int temp = 0;
		countNodeNode(temp, root);
		return temp;
	}
	int height()
	{
		int H = -1;
		heightTree(root, H);
		return H;
	}
	int width()
	{
		std::map<int, int> temp;
		widthTree(0, temp, root);
		int x = -1;
		for (auto i = temp.begin(); i != temp.end(); i++)
			if (i->second > x)
				x = i->second;
		return x;
	}
	
	Tree& operator=(Tree&);
	Tree& operator=(Tree&&);
	std::queue<T>& toQueue();
};

template <class T>
void Tree<T>::przejscie_poprzeczne(Element *&temp) const
{
	if (temp)
	{
		przejscie_poprzeczne(temp->left);
		std::cout << temp->value << std::endl;
		przejscie_poprzeczne(temp->right);
	}
}

template <class T>
void Tree<T>::przejscie_wzdluzne(Element *&temp) const
{
	if (temp)
	{
		std::cout << temp->value << std::endl;
		przejscie_wzdluzne(temp->left);
		przejscie_wzdluzne(temp->right);
	}
}

template <class T>
void Tree<T>::przejscie_wsteczne(Element *&temp) const
{
	if (temp)
	{
		przejscie_wsteczne(temp->left);
		przejscie_wsteczne(temp->right);
		std::cout << temp->value << std::endl;
	}
}

template <class T>
void Tree<T>::insert(T value)
{
	Element *newE = new Element;
	newE->value = value;
	newE->left = newE->right = nullptr;
	insertElement(root, newE);
}

template <class T>
void Tree<T>::insertElement(Element *&root, Element *&value)
{
	if (!root)
		root = value;
	else if (value->value < root->value)
		insertElement(root->left, value);
	else
		insertElement(root->right, value);
}

template <class T>
void Tree<T>::clear(Element *&temp)
{
	if (temp)
	{
		clear(temp->left);
		clear(temp->right);
		delete temp;
	}
}

template <class T>
bool Tree<T>::search(T temp)
{
	Element *ptr = root;
	while (ptr)
	{
		if (ptr->value > temp)
			ptr = ptr->left;
		else if (ptr->value < temp)
			ptr = ptr->right;
		else
			return true;
	}
	return false;
}

template <class T>
void Tree<T>::deleteSearch(Element *&temp, T value)
{
	if (!temp)
	{
		std::cout << "Nie ma takiego elementu" << std::endl;
		return;
	}
	else if (temp->value > value)
		deleteSearch(temp->left, value);
	else if (temp->value < value)
		deleteSearch(temp->right, value);
	else
		deleteElement(temp);
}

template <class T>
void Tree<T>::deleteElement(Element *&temp)
{
	Element *ptr = temp;
	if (!temp->left)
		temp = temp->right;
	else if (!temp->right)
		temp = temp->left;
	else
	{
		ptr = ptr->right;
		while (ptr->left)
			ptr = ptr->left;
		ptr->left = temp->left;
		ptr = temp;
		temp = temp->right;
	}
	delete ptr;
}

template <class T>
void Tree<T>::countNodeLeaves(int &licznik, Element *&ptr)
{
	if (ptr)
	{
		if (ptr->left || ptr->right)
		{
			countNodeLeaves(licznik, ptr->left);
			countNodeLeaves(licznik, ptr->right);
		}
		else
			licznik++;
	}
}

template <class T>
void Tree<T>::countNodeNode(int &licznik, Element *&ptr)
{
	if (ptr)
	{
		countNodeNode(licznik, ptr->left);
		countNodeNode(licznik, ptr->right);
		licznik++;
	}
}

template <class T>
void Tree<T>::heightTree(Element *&ptr, int &H, int temp)
{
	if (ptr)
	{
		if (H < temp)
			H = temp;
		heightTree(ptr->left, H, temp + 1);
		heightTree(ptr->right, H, temp + 1);
	}
}

template <class T>
void Tree<T>::widthTree(int temp, std::map<int, int> &mapa, Element *&ptr)
{
	if (ptr)
	{
		mapa[temp]++;
		widthTree(temp + 1, mapa, ptr->left);
		widthTree(temp + 1, mapa, ptr->right);
	}
}

template <class T>
Tree<T>::Tree(Tree<T> &temp)
{
	add(root, temp.root);
	std::cout << "Konstruktor kopiujacy" << std::endl;
}

template <class T>
void Tree<T>::add(Element *&newE, Element *&oldE)
{
	if (oldE)
	{
		newE = new Element;
		newE->value = oldE->value;
		add(newE->left, oldE->left);
		add(newE->right, oldE->right);
	}
	else
		newE = nullptr;
}

template <class T>
Tree<T>&  Tree<T>::operator=(Tree<T>& temp){
clear(root);
root=nullptr;
add(root,temp.root);
return *this;
}
/////////////////////////////////
template <class T>
Tree<T>::Tree(Tree<T>&& temp){
	std::cout << "Konstruktor przenoszacy" << std::endl;
	root=nullptr;
	std::swap(root,temp.root);
}/////////////////////////////////

template <class T>
Tree<T>& Tree<T>::operator=(Tree<T>&& temp){
	std::cout<<"operator przypisania przenoszacego"<<std::endl;
	std::swap(root,temp.root);
	return *this;
}

template <class T>
std::queue<T>& Tree<T>::toQueue(){
	std::queue<T>* kolejka=new std::queue<T>;
	queue(*kolejka,root);
	return *kolejka;
}

template <class T>
void Tree<T>::queue(std::queue<T>& kolejka, Element*& temp){
if(temp){
	queue(kolejka,temp->left);
	kolejka.push(temp->value);
	queue(kolejka,temp->right);
	}	
}
#endif 

//plik main.cpp
#include "tree.hpp"

int main()
{
    Tree<int> temp;
    temp.insert(3);
    temp.insert(5);
    temp.insert(6);
    temp.insert(4);
    temp.insert(1);
    temp.remove(5);
    Tree<int> temp2(temp);
    temp2.insert(6);
    std::cout << "Liscie: " << temp2.countLeaves() << std::endl;
    std::cout << "Wezly: " << temp2.countNode()<< std::endl;
    std::cout << "Wysokosc: " << temp2.height() << std::endl;
       std::cout << "Szerokosc: " << temp2.width() << std::endl;
    //   temp2.showPP();
    // Tree<int> temp3(Tree<int>());
    // temp3.insert(4); //error
    // temp3.showPP(); // error
    
}

P.S.  Jak by ktoś os mial sposób jak podzielić ten plik

2 odpowiedzi

+3 głosów
odpowiedź 23 lipca 2020 przez TOM_CPP Pasjonat (22,640 p.)

Wyrażenie:

Tree<int> temp3(Tree<int>());

nie jest definicją obiektu typu Tree<int> ale deklaracją funkcji o nazwie temp3 zwracającej obiekt typu Tree<int>. Stąd też następne linijki kodu powodują błędy w kompilacji.

Dlatego lepiej jest używać klamer { } zamiast nawiasów ( ) do definicji obiektów.

Tree<int> temp3 { Tree<int>{} };

W tym przypadku kompilator nie użyje konstruktora przenoszącego, chociaż argument jest typu rvalue, gdyż wykonana zostanie optymalizacja copy elision. Gdy jawnie zamieni się typ argumentu z rvalue na xvalue poprzez std::move, wtedy dopiero użyty zostanie konstruktor przenoszący.

0 głosów
odpowiedź 23 lipca 2020 przez Michałełe Nałogowiec (25,600 p.)

Hej, rzuciłem tylko okiem, i w main'ie powinieneś zmienić to na

	Tree<int> temp3(std::move(Tree<int>()));
	temp3.insert(4); //error
	temp3.showPP(); // error

jeśli chcesz użyć konstruktora przenoszącego.

A plik możesz jeszcze podzielić na plik z nagłówkami (.h) i na plik z definicjami funkcji (.cpp)

Napisz czy o to chodziło :)

komentarz 23 lipca 2020 przez RufinB Obywatel (1,830 p.)
funkcja move() rozwiązała problem, dzięki, ale na pliki .h i .cpp nie mogę podzielić bo to implementacja szablonu

Podobne pytania

0 głosów
1 odpowiedź 1,366 wizyt
pytanie zadane 19 października 2017 w C i C++ przez Lebowski Początkujący (330 p.)
0 głosów
1 odpowiedź 336 wizyt
pytanie zadane 5 kwietnia 2021 w C i C++ przez Beginner555 Obywatel (1,760 p.)
0 głosów
1 odpowiedź 150 wizyt
pytanie zadane 30 października 2019 w C i C++ przez Mjkl Nowicjusz (170 p.)

92,452 zapytań

141,262 odpowiedzi

319,079 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...