C++编程规范:继承与动态绑定的注意事项

需积分: 50 345 下载量 159 浏览量 更新于2024-08-10 收藏 1.28MB PDF 举报
"C++ 编程规范" 在C++编程中,有若干重要的规范和最佳实践,以确保代码的可维护性、效率和兼容性。本文将深入探讨标题和描述中提到的两个关键知识点。 首先,规则4.15强调“绝不重新定义继承而来的非虚函数”。这是因为在C++中,非虚函数不支持动态绑定,即它们的调用是基于函数调用时的对象类型,而不是指针或引用的类型。这意味着,如果你在一个派生类中重新定义了基类的非虚函数,那么通过基类指针调用这个函数,实际上将调用基类的版本,而不是派生类的版本。这可能导致意外的行为。例如: ```cpp class B { public: void mf(); //... }; class D : public B { public: void mf(); //... }; D x; B *pB = &x; // 指向D对象的B指针 D *pD = &x; // 指向D对象的D指针 pB->mf(); // 调用B::mf pD->mf(); // 调用D::mf ``` 因此,除非有特殊理由,否则应该避免覆盖非虚函数,以防止混淆和潜在错误。 其次,建议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); // 这个调用可能不符合预期 ``` 在这个例子中,`baseptr`虽然是`Derive2`的对象,但由于`FOO`的参数类型在`Derive2`中与`Base`不同,因此不能通过`baseptr`调用`Derive2`的版本。这可能导致编译错误或者运行时错误,取决于`Base`中`FOO`是否是纯虚函数以及如何实现。 遵循这些C++编程规范可以提高代码的清晰度,减少误解,并确保程序的行为符合预期。在编写C++代码时,应当重视面向对象设计的原则,如封装、继承和多态,并正确使用虚函数来实现动态绑定。同时,保持函数签名的一致性可以帮助提高代码的可读性和可维护性。