Ошибка C2660: скрытие методов в производном классе
Цель:
Совместное использование базового класса с той же функциональностью, за исключением нескольких потомков, которые просто скрывают методы (методы получения и установки), когда они создают и освобождают защищенный или закрытый указатель.
Проблема:
При повторном объявлении только метода установки я получаю эту ошибку при вызове метода установки.
1>c:\projectengine\problem\main.cpp(8): error C2660: 'cDerived::SomeClass'
: function does not take 0 arguments
Получатель на самом деле не нужен, но зачем раскрывать функциональность, если он уже есть.
Заключение:
cBase::SomeClass()
не тронут cDerived
,
При комментировании следующей строки ошибки компиляции нет (конечно):
virtual void SomeClass( cSomeClass* value ) override {}; // setter, C2660
Однако это сработает и, следовательно, ничего не изменит, повышает риск утечки памяти. С другой стороны, эта случайная производная должна наследовать остальную часть функциональности cBase
который является потомком сам по себе.
Должен ли я переписать cBase
или можно скрыть только сеттер в cDerived
?
Код с ошибкой:
main.cpp
class cSomeClass
{
};
class cBase : public cAbsoluteBase
{
public:
cBase() : m_pSomeClass( 0 ){}
virtual cSomeClass* SomeClass(){ return m_pSomeClass; }
virtual void SomeClass( cSomeClass* value ){ m_pSomeClass = value; };
protected:
cSomeClass* m_pSomeClass;
};
class cDerived : public cBase
{
private:
// hide these
//virtual cSomeClass* SomeClass() override { return m_pSomeClass; };
virtual void SomeClass( cSomeClass* value ) override {};
};
cDerived derived;
int main()
{
cSomeClass* someClass = derived.SomeClass(); // C2660
return 0;
}
2 ответа
Вам нужно объявление об использовании. В противном случае перегрузки в производном классе скрывают функции в базовом классе. (Потому что обычно это ошибка. Если вам пришлось специализировать одну перегрузку, обычно вы должны специализировать их все.)
Я не уверен, что мог бы точно следовать вашему описанию, но из фрагментов кода похоже, что вы хотите публично наследовать от класса, но удалить один из методов интерфейса базовых классов.
Это возможно, это даже можно сделать случайно, но это очень плохая идея ™. Публичное наследование - это отношения "есть". Если у вас есть класс B
публично наследуя от класса A
то, что означает это отношение, это "объекты типа B
может быть больше, чем у типа A
, но кроме этого, вы можете использовать B
где бы A
ожидается ". Очевидно, B
s могут иметь дополнительное поведение, но публичное наследование обещает, что они работают как полностью функциональные A
s. (Кстати, это известно как "принцип замещения Лискова".)
Обратите внимание, что по этой же причине один из ранних примеров наследования из учебника был полностью разбит: Square
наследовать от Rectangle
, Да, квадрат - это прямоугольник, но это не значит, что это хороший дизайн Square
публично наследовать от Rectangle
, Потому что подклассы, имеющие дополнительные ограничения по сравнению с родительскими классами, нарушают многие другие совершенно корректные и полезные коды, не соблюдая установленный контракт интерфейса. (В случае квадратов они нарушают условие контракта о том, что вы должны иметь возможность изменять стороны прямоугольника независимо друг от друга. В вашем случае вы, кажется, удаляете части интерфейса вообще.)