2014-12-09 3 views
1

Я пытаюсь получить элемент из BST для задания в классе. Некоторый из предоставленного кода мне не разрешают изменять. Инструктор создал функцию извлечения в драйвере (который я не могу изменить), который выглядит как этотФункция перегрузки/извлечения оператора назначения

static void retrieveItem(char *name) 
{ 
    Data const *data; 

    cout << ">>> retrieve " << name << endl << endl; 
    if (database->retrieve(name, data)) 
     cout << *data << endl; 
    else 
     cout << "not found" << endl; 
    cout << endl; 
} 

функция вызывается в классе BST выглядит выглядит следующим образом (до сих пор). Я не могу изменить аргументы вызова функции.

bool BST::retrieve(const char *key, Data const *& data) const 
{ 
    int rIndex = 0; 
    while (rIndex <= capacity) 
    { 
     if (strcmp(items[rIndex].data.getName(), key) == 0) 
      { 
      data = items[rIndex].data; 
      return true; 
      } 
     else if (strcmp(items[rIndex].data.getName(), key) < 0) 
      rIndex = (rIndex * 2) + 1; 
     else if (strcmp(items[rIndex].data.getName(), key) > 0) 
      rIndex = (rIndex * 2) + 2; 
    } 
    return false; 
} 

Существует массив структур называются пунктами, который выглядит как этот

struct Item 
{ 
    Data data;  // the data instance must be specified this way, NOT as a pointer 
    bool isEmpty = true; 
    int  loc = 0; 
}; 

Item *items; 

Наконец у меня есть следующие перегрузки присваивания и копирование конструкторов, реализованные для класса данных (не может изменить исходный файл на это один)

Data::Data(const Data& source) 
{ 
    strcpy(this->name, source.name); 
} 

Data& Data::operator=(const Data& data2) 
{ 
    strcpy(this->name, data2.name); 
    return *this; 
} 

Пожалуйста, поправьте меня, если я ошибаюсь, но кажется, что целью его извлечения функции в драйвере является поиск объекта данных с помощью ключа (имя) , а затем скопируйте его в аргумент данных, отправленный в функцию. К сожалению, линия

data = items[rIndex].data; 

в моей функции получения не работает с. или a ->] Я на 90% уверен. это правильный способ получить доступ к этому, но мне дана ошибка «нет подходящего типа преобразования из« данных »в« const Data * »существует»

Как еще я мог достичь этого без использования оператора перегрузки присвоений или моя реализация перегрузки не так?

+0

в общем вы не имеете в виду данные const * & data. Когда я вижу что-то подобное, это вызывает у меня подозрение – pm100

+0

@ pm100. В заявлении указано, что это код, предоставленный в задании, и они застряли с ним, независимо от того, насколько это подозрительно (и я согласен, это немного нечетное, если не сказать больше) – wakjah

ответ

1
bool BST::retrieve(const char *key, Data const *& data) const 

Второй аргумент является ссылка на указатель на константные данные, так что вы должны установить его на указатель к items[rIndex].data, а не его стоимости.

Рассмотрим следующий

void foo(int & out) 
{ 
    out = 42; 
} 

Когда он вызывается как так

// ... 
int x = 0; 
foo(x); 
std::cout << x; 

42 будут напечатаны, так как ссылка на х был принят в функцию. Ваша ситуация немного другая - вы прошли ссылку на указатель, так что абонент может получить указатель на данные аналогично описанному выше, например:

int x; // global 
// ... 
void foo(int *& out) 
{ 
    x = 42; 
    out = &x; // set out to pointer to x 
} 

int main() 
{ 
    int * ptr = nullptr; 
    foo(ptr); // foo will set ptr to the pointer to x 
    std::cout << *ptr; // prints 42 
} 

Опять же, 42 будут напечатаны. Обратите внимание на использование унарного ref, & и deref, *, операторов для получения указателя на x и разыменования ptr, чтобы извлечь его значение.

В стороне, нельзя сказать, как сломалась ваша реализация Data::operator=, не видя больше класса. Как бы то ни было, он разрушен, потому что неопределенное поведение заключается в использовании strcpy на перекрывающихся областях памяти - это произойдет, если кто-то попытается присвоить экземпляр объекта самому себе (см. strcpy).Для случаев, отличных от самоопределения, это верно только в том случае, если для назначения назначения всегда достаточно места для строки в источнике. В противном случае вы будете писать в нераспределенную память. Кроме того, если есть дополнительные переменные-члены, они также нуждаются в копировании.

+0

Так что мне нужно создать отдельную переменную-указатель и указать ей на «items [rIndex] .data', а затем использовать этот указатель как второй аргумент? Назначение для назначения - объект данных в функции драйвера, хотя, не так ли? И нет дополнительных членов – FutureShocked

+0

Проблема в 'BST :: retrieve', а не код вызова. – wakjah

+0

Я все еще не понимаю, как бы я это исправил – FutureShocked