Функция Friend не может получить доступ к личному члену данных (c ++) - PullRequest
0 голосов
/ 23 октября 2018

Я искал много разных вопросов и не смог найти решения, соответствующего моей конкретной проблеме.У меня есть этот файл заголовка для очереди:

#ifndef HEADERFILE
#define HEADERFILE
#include <iostream>
#include <vector>
using namespace std;

template<class myType>
class Queue{
  private:

    int size;
    vector<myType> list; 

  public:

    Queue(int);
    void Enqueue(myType);
    myType Dequeue();
    myType PeekFront();
    int length();
    void empty();
    myType Index(int);
    friend void printArray();

};

#endif

Вопрос, о котором идет речь, friend void printArray.Вот файл реализации:

#include "queueTask1.h"
#include <vector>
#include <iostream>

using namespace std;

(Other function implementations)

void printArray(){
    for (int i = 0; i < list.size(); i++){
        cout << list.at(i) << ", ";
    }
    cout << endl;
}

Ошибка при попытке запустить это утверждает, что

'список' не объявлен в этой области

однако он объявлен в заголовочном файле, и все остальные функции-члены работают нормально.По какой-то причине printArray не может найти элемент приватных данных list, хотя это должна быть функция друга.

Ответы [ 4 ]

0 голосов
/ 23 октября 2018

Сам, я бы сделал это:

template<class myType>
class Queue{
  // snip ...
  public:
  // snip ...
    template<class F>
    friend void foreach_element(Queue& q, F&& f) {
      for(auto&&e:list) f(e);
    }
    template<class F>
    friend void foreach_element(Queue const& q, F&& f) {
      for(auto&&e:list) f(e);
    }
};
template<class myType>
void printArray(Queue<myType> const& q) {
  foreach_element(q, [](auto&& e){ std::cout << e << ","; } );
  std::cout << std::endl;
}

обратите внимание, что реализация printArray должна идти в заголовке, так как это шаблонная функция.

Я выставилforeach_element чтобы получить элементы, а затем printArray быть не-другом, который его использует.

0 голосов
/ 23 октября 2018

Объявление очень хорошо, но над каким экземпляром этого класса вы работаете?list доступен, если у вас есть object.list, но просто list ни к чему не относится.Передайте экземпляр вашего класса и используйте его для доступа к list.

Что-то вроде:

void printArray(const Queue& object)
0 голосов
/ 23 октября 2018

list является нестатическим элементом данных.Это означает, что есть один list для каждого объекта.Так как он зависит от объекта, вам нужен объект для доступа к list.Самый простой способ сделать это - передать объект в функцию, подобную

// forward declare the function, unless you want to define the function inside the class
template<class ElementType>
friend void printArray(const Queue<ElementType>&);

template<class myType>
class Queue{
    //...
    // declare the friendship
    template<class ElementType>
    friend void printArray(const Queue<ElementType>&);
    //...
};

// define the function
template<class ElementType>
void printArray(const Queue<ElementType>& q)
{
    for (int i = 0; i < q.list.size(); i++){
        cout << q.list.at(i) << ", ";
    }
    cout << endl;
}   

. Вам также нужно переместить реализацию Queue в заголовочный файл, поскольку это temaplte.Для получения дополнительной информации см. Почему шаблоны могут быть реализованы только в заголовочном файле?

0 голосов
/ 23 октября 2018

Вам нужно передать экземпляр класса в printArray(), а затем вы можете получить доступ к закрытым членам этого экземпляра.В противном случае printArray() не знает, какой экземпляр использовать.

void printArray(Queue &myQueue){
    for (int i = 0; i < myQueue.list.size(); i++){
        cout << myQueue.list.at(i) << ", ";
    }
    cout << endl;
}
...