Inheritance 私有继承和非虚拟接口

Inheritance 私有继承和非虚拟接口,inheritance,d,non-virtual-interface,Inheritance,D,Non Virtual Interface,所以我对D感兴趣已经有一段时间了,而我在一段时间前就搞砸了。我已经开始重新审视它,我真的很喜欢它正在努力实现的,但我有一个关于我最喜欢的C++设计选项的疑虑…非虚拟接口 我喜欢这种设计的地方在于它允许在继承层次结构的“顶层”进行前后条件检查、日志记录和资源管理。这允许设计人员指定一组相关类的所有公共功能,并将类的可自定义部分分解为非常小的功能。它还减少了需要在子类中编写的功能量。另外,因为虚拟扩展点是私有的,所以它不会污染接口,也不会允许用户直接调用特定于实现的函数(这真的很关键) 有没有办法在

所以我对D感兴趣已经有一段时间了,而我在一段时间前就搞砸了。我已经开始重新审视它,我真的很喜欢它正在努力实现的,但我有一个关于我最喜欢的C++设计选项的疑虑…非虚拟接口

我喜欢这种设计的地方在于它允许在继承层次结构的“顶层”进行前后条件检查、日志记录和资源管理。这允许设计人员指定一组相关类的所有公共功能,并将类的可自定义部分分解为非常小的功能。它还减少了需要在子类中编写的功能量。另外,因为虚拟扩展点是私有的,所以它不会污染接口,也不会允许用户直接调用特定于实现的函数(这真的很关键)

有没有办法在D中实现这一点

C++中的例子(未经测试,未编译……仅供说明)。

class收音机{
公众:
收音机(标准::字符串id、电台默认电台、RxChip芯片)
:defaultStation(defaultStation),
身份证,
芯片(芯片){
}
无效开启(){
log.trace(“收音机已打开:id:[%s]”,id.c_str());
doEnableRx();
doPostable();
设置站(默认站);
}
无效关闭(){
log.trace(“无线电已关闭:id:[%s]”,id.c_str());
doDisableRx();
doPowerOff();
}
void tune(){
log.trace(“调优”);
findAllStations();
}
无效设置站(站目标){
logStationChange(目标公司);
DosetRxHippassFilter(目标);
}
无效设置芯片(RxChip芯片){
rxChip=芯片;
}
RxChip getChip(){
返回rxChip;
}
私人:
//不要以“do”开头,因为这被视为“正常”虚拟函数。
虚拟void findAllStations(){
chip.setFrequency(chip.getLowFreq());
setChipToNextTunedPoint();
Station stat(chip.getFrequency(),tunedStations.size());
调谐状态。推回(stat);
}
虚拟bool setChipToNextTunedPoint(){
if(chip.isTuned()){
while(istune&&chip.getFrequency()
当然可以。对于非虚拟成员函数,要么将其设置为
final
(这样编译器就可以优化其虚拟性),要么将其模板化,然后保证它是非虚拟的,因为模板函数从来都不是虚拟的。为了模板化一个没有模板参数的函数,只需给它一个空的模板参数列表。e、 g

void setChip(RxChip chip) {...}
变成

void setChip()(RxChip chip) {...}
对于虚拟函数,只需将其设置为
受保护
。目前,
private
package
从来都不是虚拟的,因此如果您希望函数是虚拟的,则需要将其设置为
public
protected
,通过将其设置为
protected
,公共API无法访问它。你不能完全的去让它成为代码>私有< /代码>,就像你在C++中所做的那样,但可以说,这并不能真正地为你买任何东西,因为重写函数仍然可以被它所属的类调用。因此,使它成为私有的就是使它不能调用基类版本(通常是纯虚拟/抽象的)


然而,我要指出的是,如果您只想要合同,那么D的
in
out
块支持多态性。所以,你甚至不需要NVI。此时,您只需要让基类函数具有
in
out
块,其中包含您想要的任何in-contracts和out contracts,并且在调用派生函数时将调用它们。这只适用于您希望用于前置和后置条件的断言,但在某些情况下,它不需要NVI。

有人知道为什么语法高亮显示在代码示例中不起作用吗?我认为我从未在stackoverflow上的任何D代码中看到过语法高亮显示。至于合同,
中的
与多态性不太兼容,因为它只执行
块中派生最多的
<代码>输出
工作正常,但NVI中的
工作正常。所以我想我应该接受一个警告,我应该使用protected而不是private,这样就可以了。还感谢您对合同的深入了解。。。我从中得到的是,我应该使用NVI,并在其上使用in-contract,然后我可以在受保护的扩展点函数上使用多个out-contract。谢谢,小伙子们。
void setChip()(RxChip chip) {...}