При использовании MS Visual Studio 2019 при перегрузке operator<<
я получаю следующие ошибки:
Severity Code Description Project File Line Suppression State
Error C2248 'Instruction::Device_Impedance::m_minimum_ohms': cannot access private member declared in class 'Instruction::Device_Impedance' friend_ostream_namespace device_impedance.cpp 13
Severity Code Description Project File Line Suppression State
Error C2248 'Instruction::Device_Impedance::m_maximum_ohms': cannot access private member declared in class 'Instruction::Device_Impedance' friend_ostream_namespace device_impedance.cpp 14
#ifndef INSTRUCTION_DEVICE_IMPEDANCE_HPP
#define INSTRUCTION_DEVICE_IMPEDANCE_HPP
#include <string>
#include <iostream>
namespace Instruction
{
class Device_Impedance
{
public:
Device_Impedance();
Device_Impedance(const unsigned int min_ohms,
const unsigned int max_ohms);
//! Constructor -- Copy
Device_Impedance(const Device_Impedance& di);
//! Destructor
~Device_Impedance();
public:
Device_Impedance&
operator=(const Device_Impedance& di);
friend std::ostream& operator<< (std::ostream& out, const Instruction::Device_Impedance& di);
//--------------------------------------------------------------------------
// Public Methods
//--------------------------------------------------------------------------
public:
const std::string& get_name() const override;
//--------------------------------------------------------------------------
// Private Members
//--------------------------------------------------------------------------
private:
unsigned int m_minimum_ohms;
unsigned int m_maximum_ohms;
};
} // End namespace Instruction
/*! @} // End Doxygen Group
*/
#endif // INSTRUCTION_DEVICE_IMPEDANCE_HPP
#include "device_impedance.hpp"
using namespace Instruction;
/*!
* \details Output the instruction name to the stream.
*/
std::ostream&
operator<< (std::ostream& out, const Instruction::Device_Impedance& di)
{
out << di.get_name()
//***** The next two lines are causing the error.
<< " " << di.m_minimum_ohms
<< ", " << di.m_maximum_ohms
<< "\n";
return out;
}
const std::string&
Device_Impedance ::
get_name() const
{
static std::string instruction_name{"DEVICE_IMPEDANCE"};
return instruction_name;
}
Правильный ли у меня синтаксис пространства имен для реализации operator<<
?
Можете ли вы опубликовать минимально воспроизводимый пример и избежать визуального мусора? Я не могу воспроизвести проблему. получаю error: 'const std::string& Instruction::Device_Impedance::get_name() const' marked 'override', but does not override
@3CxEZiVlQ: Сообщения об ошибках остаются неизменными. Хотите снимок экрана?
Нет, ваш синтаксис неверен. using namespace
не приводит к тому, что следующие объявления/определения будут находиться в этом пространстве имен.
Либо используйте namespace Instruction { /*definition of operator<< here*/ }
, как в заголовке, либо укажите имя в определении:
std::ostream&
Instruction::operator<< (std::ostream& out, const Instruction::Device_Impedance& di)
В противном случае вы определяете глобальную перегрузку ::operator<<
, а не ту friend
ed, которая находится в пространстве имен, охватывающем класс, то есть в Instruction
.
Однако using namespace
достигает того, что вам не нужно уточнять имена для целей поиска, например. Instruction::
в параметре функции для него избыточен. То же самое справедливо и для объявления в классе.
Кроме того, как отмечено в комментариях к вопросу, override
на get_name
также неверно, потому что эта функция на самом деле не является переопределением.
Квалификация Instruction::operator<<
по-прежнему выдавала ошибку. Однако размещение реализации в namespace Instruction { /*...*/}
сработало (ошибок не возникло).
Я почти уверен, что вы хотите населять, а не подавлять, но недостаточно уверен, чтобы редактировать самому.
@Thomas Matthews - Стандарт гласит: «Объявление друга никогда не связывает никаких имен». Я понимаю, что когда вы объявляете дружественную функцию внутри класса, она не вводит новое имя в окружающее пространство имен. Объявление друга — это просто декларация о намерении разрешить указанной функции или классу доступ к закрытым и защищенным членам класса.
@user4581301 user4581301 Да, конечно.
@ThomasMatthews У меня также работает с квалифицированным именем: godbolt.org/z/oeGYbEnWc
namespace Instruction {
class Device_Impedance {
public:
friend std::ostream& operator<<(std::ostream& out,
const Instruction::Device_Impedance& di);
private:
unsigned int m_minimum_ohms;
unsigned int m_maximum_ohms;
};
} // namespace Instruction
Приведенный выше свернутый класс объявляет друга operator<<
в пространстве имен Instruction
.
using namespace Instruction;
std::ostream& operator<<(std::ostream& out,
const Instruction::Device_Impedance& di) {
out << di.get_name() << " " << di.m_minimum_ohms << ", "
<< di.m_maximum_ohms << "\n";
return out;
}
Приведенный выше код определяет operator<<
в глобальном пространстве имен, но не определяет друга operator<<
в пространстве имен Instruction
.
Определение должно находиться в пространстве имен
namespace Instruction {
std::ostream& operator<<(std::ostream& out,
const Instruction::Device_Impedance& di) {
out << di.get_name() << " " << di.m_minimum_ohms << ", "
<< di.m_maximum_ohms << "\n";
return out;
}
} // namespace Instruction
Или в классе
namespace Instruction {
class Device_Impedance {
public:
friend std::ostream& operator<<(std::ostream& out,
const Instruction::Device_Impedance& di) {
out << di.get_name() << " " << di.m_minimum_ohms << ", "
<< di.m_maximum_ohms << "\n";
return out;
}
private:
unsigned int m_minimum_ohms;
unsigned int m_maximum_ohms;
};
} // namespace Instruction
Пожалуйста, опубликуйте полные дословные сообщения об ошибках на панели «Вывод сборки».