Должна ли функция друга быть в одном файле?
Я на самом деле тестирую файл, и у меня возникает ситуация, когда мне нужно получить доступ к некоторым защищенным членам класса из main.cpp. Я пытался добавить, main()
как друг, не получилось и узнал, что это не будет работать, поэтому я переместил все в main()
к test ()
и сделал test()
как друг. все же это показывает ошибку.
Пример будет
//--File.hpp
namespace Files {
class File {
public:
File(long word_):word(word_) {}
protected:
long word;
private:
friend int test();
};
}//ns:Files
//--List_File.hpp
namespace Files {
class List_File :public File {
public:
List_File() : File(sizeof(int) + sizeof(long)) {}
private:
friend int test();
};
}//ns:Files
//--main.cpp
using namespace Files;
int test() {
File *pd = new List_File();
assert(pd->word == 12); //LINE 34
return 0;
}
int main() {
test();
return 0;
}
// в строке 34 говорится об ошибке: Base::value защищено. Пожалуйста посоветуй.
g++ -O -Wall -Wno-unused -o a.out File.cpp List_File.cpp Data_File.cpp
Free_List_File.cpp main.cpp
File.hpp: In function ‘int test()’:
File.hpp:30:7: error: ‘long int Files::File::word’ is protected
main.cpp:34:16: error: within this context
make: *** [a.out] Error 1
4 ответа
Нет, он определенно не обязательно должен находиться в том же файле, но он, очевидно, должен "знать", что такое класс, то есть: заголовок, который имеет определение класса, должен быть включен в файл, в котором реализована функция. Ваш код должен быть в порядке, как прокомментировано.
после того, как вы добавили некоторый контекст
Ваш test
функция не в Files
Пространство имен. Если вы хотите, чтобы это было в глобальном контексте, вы должны рассматривать это как "::test
"внутри пространства имен, иначе компилятор может ожидать"Files::test
"быть другом, а не функцией"::test
"как в вашем случае. Не могу найти формальную стандартную ссылку, но я почти уверен, что это так. Обратите внимание, что вы выполняете предварительное объявление здесь, поэтому по умолчанию нет возврата к верхнему уровню области действия для разрешение имен.
Может быть, вы пропустили декларацию наследования в производном классе?
class Derived : public Base {
Я проверил ваш код (с включенным объявлением наследования), и он не выдал ошибку
Литтедев прав!! Обновлен код в соответствии с комментариями Литтедев..
//--File.hpp
namespace Files {
class File {
public:
File(long word_):word(word_) {}
protected:
long word;
private:
friend int test();
};
}//ns:Files
//--List_File.hpp
namespace Files {
class List_File :public File {
public:
List_File() : File(sizeof(int) + sizeof(long)) {} \
private:
friend int test();
};
}//ns:Files
//--main.cpp
namespace Files{
int test() {
File *pd = new List_File();
assert(pd->word == 12); //LINE 34
return 0;
}
int main() {
Files::test();
return 0;
}
}
Я предполагаю, что вы пытаетесь получить доступ к защищенной переменной вне области определения класса Files. Я бы порекомендовал функцию, которая возвращает переменное слово при его вызове, и использовал бы ее вместо попытки доступа к защищенной переменной вне определения класса. Я могу ошибаться в том, что я не совсем уверен, какова область действия защищенной переменной (независимо от того, ограничена ли она только объявлениями класса или доступ к ней возможен вне определения класса), но я почти уверен, что я прав, потому что защищенные переменные похожи на частные переменные. Они доступны только в пределах класса. Поправь меня, если я ошибаюсь.
РЕДАКТИРОВАТЬ: О, мне жаль, я не понял, что ты делал. littleadv прав, ваше объявление функции не находится в пространстве имен файлов.