2016-01-07 5 views
0

I'm quiet new on C++ и в настоящее время учится понимать интеллектуальные указатели. Поэтому я в настоящее время работаю над небольшой консольной программой для вставки, поиска и удаления песен ... для обучения цели, чтобы привыкнуть к вещи =)получение ошибки на векторе <unique_ptr <X>> v

Вот мой код:

Song.hpp

#pragma once 
#include <vector> 
#include <memory> 
#include <string> 

class Song 
{ 

public: 
    typedef std::unique_ptr<Song> pSong; 

public: 
    Song(); 
    ~Song(); 
    void setTitle(std::string title); 
    void setArtist(std::string artist); 
    void checkSong(std::string item, int iterator); 
    void get(); 

private: 
    std::string _title; 
    std::string _artist; 
}; 

Song.cpp

#include "Song.hpp" 
#include <iostream> 



Song::Song() 
{ 
} 


Song::~Song() 
{ 
} 

void Song::setTitle(std::string title) 
{ 
    _title = title; 
} 

void Song::setArtist(std::string artist) 
{ 
    _artist = artist; 
} 

void Song::checkSong(std::string item, int iterator) 
{ 
    if (_artist == item || _title == item) 
    { 
     std::cout << "Item found on Slot: " << iterator << std::endl; 
    } 
    else 
    { 
     std::cout << "No item found!" << std::endl; 
    } 
} 

void Song::get() 
{ 
    std::cout << _artist << " - " << _title << std::endl; 
} 

main.cpp

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <memory> 
#include "Song.hpp" 

//prototype 
void IntVector(); 
void SongVector(); 
Song* setSong(std::string title, std::string artist); 
void find(std::string item, std::vector<Song::pSong> v); 


std::vector<Song::pSong> SongList; 

int main() 
{ 
    int k; 
    SongVector(); 
    std::cin >> k; 
    return 0; 
} 

void IntVector() 
{ 
    // Create Vector 
    std::vector<std::unique_ptr<int>> v; 

    // Create a few unique_ptr<int> instances and fill them with ints 
    v.push_back(std::unique_ptr<int>(new int(30))); 
    v.push_back(std::unique_ptr<int>(new int(600))); 
    v.push_back(std::unique_ptr<int>(new int(200))); 
    v.push_back(std::unique_ptr<int>(new int(20))); 
    v.push_back(std::unique_ptr<int>(new int(200))); 
    v.push_back(std::unique_ptr<int>(new int(160))); 
    v.push_back(std::unique_ptr<int>(new int(4))); 
    v.push_back(std::unique_ptr<int>(new int(5))); 
    v.push_back(std::unique_ptr<int>(new int(315))); 


    // define vector<int> for storing values of the unique_ptr 
    std::vector<int> intList; 

    for (int i = 0; i < v.size(); i++) 
    { 
     // get memory-adress of each element 
     auto result = v[i].get(); 
     // store value of result-pointer in Vector 
     intList.push_back(*result); 
     std::cout << *result << std::endl; 
    } 

    // Sort int of new Vector 
    std::sort(intList.begin(), intList.end()); 

    // Loop through intList and cout 
    for (int i = 0; i < intList.size(); i++) 
    { 
     std::cout << intList[i] << std::endl; 
    } 

} 

void SongVector() 
{ 

    Song* first = setSong("Afroki","Steve Aoki"); 
    Song* secound = setSong("Hype", "Steve Aoki"); 
    Song* third = setSong("Madness", "Steve Aoki"); 
    Song* fourth = setSong("Cake Face", "Steve Aoki"); 
    SongList.push_back(Song::pSong(first)); 
    SongList.push_back(Song::pSong(secound)); 
    SongList.push_back(Song::pSong(third)); 
    SongList.push_back(Song::pSong(fourth)); 

    for (const auto& song : SongList) 
    { 
     song->get(); 
    } 

    find("Madness", SongList); 
} 

Song* setSong(std::string title, std::string artist) 
{ 
    Song* song = nullptr; 
    song = new Song; 
    song->setArtist(artist); 
    song->setTitle(title); 
    return song; 
} 


void find(std::string item, std::vector<Song::pSong> v) 
{ 

    int i = 0; 
    for (const auto& song : v) 
    { 
     song->checkSong(item,i); 
     i++; 
    } 
} 

я получил следующую ошибку:

std::unique_ptr<Song,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function 
1>   with 
1>   [ 
1>    _Ty=Song 
1>   ] 

я узнал, что эта ошибка возникает только при вызове моей находки (...) - метод, поэтому я Угадаю, что где-то там есть моя ошибка, но я просто могу сделать t find out, what I. Поблагодарили бы за вашу помощь.

+0

Я думаю, вы получите больше ответов, если бы вы отварили свою программу до минимального количества строк кода, которые все еще проявляют проблему. Это также, возможно, поможет вам понять, в чем проблема. –

+0

Конкретная функция - это конструктор копирования 'unique_ptr'. Эта функция удаляется, чтобы убедиться, что указатель ** является уникальным. Таким образом, вы не можете скопировать указатель или вектор, содержащий такие указатели. –

+0

Shachar Shemesh Sry, но подумал, что лучше разместить все это, а не маленькие кусочки. Вырежет мой код в будущих вопросах ... THX для совета, также ваш Бо Перссон ... это полностью делает смысл, когда переосмысление =) – cFx

ответ

4

std::unique_ptr Предоставить уникальную собственность (имя хны), а это означает, что вы не можете копировать экземпляр std::unique_ptr - что будет означать совместное владение. Когда вы передаете std::vector<std::unique_ptr<whatever>> по значению, вы создаете копию векторного экземпляра, который пытается скопировать каждый элемент. Так простое решение было бы передать std::vector экземпляр по константной ссылке (как вы не имеете намерений изменить вектор):

void find(const std::string &item, const std::vector<Song::pSong>& v); 

рядом фиксируя проблему пролета (Const) ссылка является более эффективной для нетривиальных объектов, так вы можете также использовать его для std::string

в вашей intVector() функции:

for (int i = 0; i < v.size(); i++) 
    { 
     // get memory-adress of each element 
     auto result = v[i].get(); 
     // store value of result-pointer in Vector 
     intList.push_back(*result);   
     std::cout << *result << std::endl; 
    } 

вы действительно не нужно, чтобы получить сырой указатель, просто использовать std::unique_ptr себя:

for (int i = 0; i < v.size(); i++) 
{ 
    // get smart pointer for each element 
    const auto &result = v[i]; 
    // store value of result-pointer in Vector 
    intList.push_back(*result); 
    std::cout << *result << std::endl; 
} 
1
void find(std::string item, std::vector<Song::pSong> v) 

Вы должны передать векторы по ссылке. Добавить &.

void find(std::string item, std::vector<Song::pSong>& v) 

Не забудьте также изменить прототип функции.