可以强制从抽象基类继承的类只在基类中定义公共方法吗
Can you force classes inheriting from abstract base class to only have the public methods defined in base case?
是否可以有一个抽象类,但FORCE实现类只能有抽象类中的公共方法?
我不在乎私有方法是如何工作的,但我想强制类只有一个公共方法。
例如,假设我有以下抽象类:
class MyObjectTransform
{
public:
virtual ~MyObjectTransform()
{
}
virtual MyObject transform(MyObject input) = 0;
};
然后,我想强制所有从MyObjectTransform
继承的对象只有一个(构造函数除外)公共方法transform
。我不在乎继承类有什么私有方法。这可能吗?
更新:这里的目标是迫使开发人员只通过一个方法公开功能。例如,考虑这种情况:
class ATransform
{
private:
MyObject A_Stuff(MyObject input);
public:
override MyObject transform(MyObject input)
{
return this->A_stuff(input);
}
};
class BTransform
{
public:
MyObject B_Stuff(MyObject input);
override MyObject transform(MyObject input)
{
return this->B_stuff(input);
}
};
这里的问题是开发人员可以直接调用B_Stuff
。我想防止这种情况发生。
不,你不能。派生类可以定义他们想要的任何公共成员函数。没有办法对此加以限制。
更新:
如果您不希望用户访问B_Stuff,请将其声明为private。如果您希望从BTransform派生的类也可以使用它,请将它声明为受保护的
class BTransform
{
private:
MyObject B_Stuff(MyObject input);
Public:
override MyObject transform(MyObject input)
{
return this->B_stuff(input);
}
};
但是您不能使用C++语言强制声明B_Stuff为私有或受保护。必须将其定义为一项政策。
您已经在使用针对此场景的机制:它是抽象基类!
它的全部意义在于,该层次结构中的所有类都旨在支持通过对基类MyObjectTransform
的指针/引用进行多态性使用。这样,用户就不知道实现类有什么公共方法,因为他只能使用通过基类可用的方法:transform
。
如果您想更严格地执行这一点,那么根本不要在头中公开实现类的声明。隐藏BTransform
和ATransform
,只公开工厂函数和抽象基类。
std::unique_ptr<MyObjectTransform> makeATransform()
{
return { new ATransform };
}
std::unique_ptr<MyObjectTransform> makeBTransform()
{
return { new BTransform };
}
这样,客户端/开发人员的代码看起来是这样的:
int main()
{
auto btransform = makeBTransform();
btransform->B_Stuff(input); // ERROR, MyObjectTransform doesn't have this member function.
btransform->transform(input); // FINE
}
用户只能使用基类中的一个公共方法。
当然,有人可以将指针投射到BTransform*
,然后做任何他们想做的事情(前提是他们可以发现BTransform
的实际实现是什么,因为我们隐藏了它)。但是,正如chmike所写的那样,为了防止public
方法被访问,你必须将它们设置为private
。正如赫伯·萨特所说:
C++保护墨菲,而不是马基雅维利
在C++中,公共函数应该是非虚拟的,而虚拟函数应该是私有的(析构函数除外)。应用这个准则会使问题完全消失,因为类的客户端只剩下一个公共函数可以调用:
class MyObjectTransform
{
public:
virtual ~MyObjectTransform()
{
}
MyObject transform(MyObject input) // non-virtual!
{
// can do extra stuff, e.g. check input for validity
doTransform(input);
}
private:
virtual MyObject doTransform(MyObject input) = 0;
};
class ATransform : public MyObjectTransform
{
private:
MyObject A_Stuff(MyObject input);
MyObject doTransform(MyObject input) override
{
return this->A_Stuff(input);
}
};
class BTransform : public MyObjectTransform
{
private:
MyObject B_Stuff(MyObject input);
MyObject doTransform(MyObject input) override
{
return this->B_Stuff(input);
}
};
- 如何定义一个纯抽象基类
- 使用子类覆盖基类中定义的函数
- 将抽象基类中的所有纯虚函数定义为 varaidaic 模板
- 使(虚拟)函数在大多数派生类中无法访问中间基类中可访问,定义良好?
- 为什么为派生类定义复制构造函数需要定义基类的默认构造函数?
- Linux c++.在预加载的共享库中定义的基类的崩溃调用函数
- 基类可以声明虚拟方法但不定义它吗?仍然在派生类中定义
- 错误:基类在从基类父派生类 Son 时未定义
- 无法使用在子类中定义的虚拟getter实现基类
- 如何在基类中定义静态接口,并确保该接口必须在派生类中实现
- Qt基类函数定义
- 当在基类中定义枚举时,qml中的Q_ENUM未定义值
- 即使基类和派生类只使用基元数据类型,我是否需要定义虚拟析构函数
- C++未定义的基类
- 自定义异常中的用户定义的空构造函数,具有多个继承和抽象基类
- 为什么不允许在非推导上下文中使用基类定义,以及如何解决这个问题
- CRTP和基类定义的类型的可见性
- 从继承的虚拟基类定义纯虚拟函数
- 当我使用根据基类定义的成员函数指针时,编译器如何调用派生成员函数?
- 派生类通过基类定义函数