C++编程规范:避免重定义非虚函数与同名函数

需积分: 50 99 下载量 62 浏览量 更新于2024-08-07 收藏 980KB PDF 举报
"C++语言编程规范,强调了继承与多态相关的编程规范,特别是关于非虚函数和虚函数的使用,以及避免派生类中定义与基类同名但参数类型不同的函数。" 在C++编程中,继承是面向对象设计的重要特性,它允许创建一个新类(派生类)来扩展或修改已存在的类(基类)的功能。然而,继承过程中需要注意一些关键的规范,以确保代码的可维护性和正确性。 **规则4.15 绝不重新定义继承而来的非虚函数** 这个规则强调了不要在派生类中重定义基类的非虚函数。非虚函数在调用时是静态绑定的,即编译器在编译时期就决定了调用哪个版本的函数,因此,如果通过基类指针调用非虚函数,实际执行的是基类的版本,而不是派生类可能重定义的版本。例如: ```cpp class B { public: void mf(); //... }; class D : public B { public: void mf(); //... }; D x; B *pB = &x; D *pD = &x; pB->mf(); // 调用 B::mf pD->mf(); // 调用 D::mf ``` 在这里,`pB->mf()` 和 `pD->mf()` 的行为是不同的,因为 `mf` 在基类 `B` 中是非虚函数。这可能导致意外的行为,尤其是当你期望通过基类指针调用派生类的成员函数时。 **建议4.5 避免派生类中定义与基类同名但参数类型不同的函数** 这个建议指出,即使函数名称相同,但参数类型不同的函数在C++中被视为完全不同的函数。这意味着,即使在派生类中定义了一个与基类同名但参数列表不同的函数,它们也不会相互覆盖。这种情况下,使用基类指针调用该函数,将始终调用基类中的版本,而不是派生类的版本。例如: ```cpp class Base { public: virtual long FOO(const A, const B, const C) = 0; }; class Derive1 : public Base { public: long FOO(const A, const B, const C); }; class Derive2 : public Derive1 { public: long FOO(const A, B, const C); }; Base* baseptr = new Derive2(); baseptr->FOO(A, B, C); // 实际调用的是 Base 或 Derive1 中的 FOO,而不是 Derive2 中的 FOO ``` 在上述例子中,`baseptr` 是一个指向 `Derive2` 对象的指针,但由于参数类型不同,`FOO` 函数并不构成重载,因此不会调用 `Derive2` 中的版本,而是调用最接近的匹配版本,可能是 `Base` 或 `Derive1` 中的 `FOO`。 遵循这些规范,可以避免不必要的混淆和错误,提高代码的可读性和可维护性。在编写C++代码时,特别是在设计类的继承层次结构时,应谨慎处理虚函数和非虚函数的使用,以及派生类与基类之间函数的命名和参数列表。这有助于确保程序的正确性,并减少因多态性理解不足导致的问题。