【发布时间】:2010-11-25 03:39:45
【问题描述】:
我一直在与我的同事讨论是否在被覆盖的方法前加上 virtual 关键字,或者只在原始基类中添加前缀。
我倾向于在所有虚拟方法(即涉及 vtable 查找的方法)前加上 virtual 关键字。我的理由有三个:
鉴于 C++ 缺少覆盖 关键字,虚拟的存在 关键字至少会通知您 该方法涉及查找和 理论上可以被覆盖 进一步的专业化,或可能是 通过指向更高级别的指针调用 基类。
一直使用这种风格 意味着,当你看到一个方法时 (至少在我们的代码中)没有 virtual 关键字,你可以 最初假设它既不是 源自基础或专业 在子类中。
如果由于某些错误, virtual 已从 IFoo 中删除,所有 孩子们仍然可以正常工作 (CFooSpecialization::DoBar 会 仍然覆盖 CFooBase::DoBar, 而不是简单地隐藏它)。
据我了解,反对这种做法的论点是,“但该方法不是虚拟的”(我认为这是无效的,并且源于对虚拟性的误解),以及“当我看到 virtual 关键字时,我希望这意味着有人从中派生,然后去寻找他们。”
假设的类可能分布在多个文件中,并且有几个专业化。
class IFoo {
public:
virtual void DoBar() = 0;
void DoBaz();
};
class CFooBase : public IFoo {
public:
virtual void DoBar(); // Default implementation
void DoZap();
};
class CFooSpecialization : public CFooBase {
public:
virtual void DoBar(); // Specialized implementation
};
从风格上讲,您会从两个派生类中删除 virtual 关键字吗?如果是这样,为什么? Stack Overflow 对此有何想法?
【问题讨论】:
-
我很想看看 Bjarne(或 C++ 委员会)为什么允许在派生类中省略 virtual 的理由。这个理由可能比你的同事提供了更令人信服的理由来实际省略它。不过,也许只是在某些情况下。
-
不幸的是,规范中没有包含任何理由。它只是说它是“合法但多余(具有空语义)”。不过,如果有任何关于理由的记录,听听会很有趣。
-
我没有“设计与进化”的副本,它可能包含也可能不包含任何内容。
-
我想指出,从 C++11 开始,您还可以使用
override说明符来指定一个函数是虚函数并覆盖另一个函数;这样做还允许编译器在函数没有覆盖任何内容时向您提供错误消息。以您的示例为例,CFooBase和CFooSpecialization将具有virtual void DoBar() override;。 -
@JustinTime 我认为人们想要的是一种标准强制的方式来要求描述性vfunc声明,而不是记住故意输入另一个完全可选的关键字,无需打开依赖于编译器的警告。但我认为现在就它会破坏什么以及会导致的习惯性反弹而言为时已晚。也就是说,这是
g++的诀窍:stackoverflow.com/questions/29145476/…
标签: c++ methods coding-style virtual-functions