3

目标:

共享具有相同功能的基类,但只有少数后代在实例化和释放受保护或私有指针时仅隐藏方法(getter 和 setter)。


问题:

仅在重新声明 setter 时,我在调用 getter 时收到此错误。

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还是可以只隐藏 setter cDerived


有错误的代码:

主文件

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; 

} 
4

2 回答 2

2

你需要一个using声明。否则,派生类中的重载会隐藏基类中的函数。(因为通常这是一个错误。如果你必须专门化一个重载,通常你必须专门化所有的重载。)

于 2012-08-06T08:15:08.360 回答
0

我不确定我是否能准确地遵循您的描述,但从代码片段来看,您似乎想从一个类公开继承,但删除基类接口的方法之一。

这是可能的,甚至有可能意外发生,但这是一个非常糟糕的主意™。公共继承是一种“is-a”关系。如果你有一个从 classB公开继承的类A,那么声明这种关系的意思是“类型的对象B可能比类型的对象大A,但除此之外,你可以在B任何A预期的地方使用 a。” 显然Bs 可能有额外的行为,但公共继承承诺它们可以作为全功能A的 s 工作。(顺便说一下,这被称为“里氏替换原则”。)

请注意,这也是为什么早期教科书的继承示例之一被彻底破坏的原因:Square继承自Rectangle. 是的,正方形是长方形,但这并不意味着Square公开继承自Rectangle. 因为子类对其父类有额外的限制,因为不遵守已建立的接口契约,会破坏许多原本完全有效和有用的代码。(在正方形的情况下,它们违反了合同条款,即您应该能够相互独立地更改矩形的边。在您的情况下,您似乎完全删除了部分界面。)

于 2012-08-07T13:43:25.200 回答