任何时候都适用的20个C++技巧 <12-13> Object-oriented Design

12 and 13: Object-oriented Design

  虽然C++支持多种非常有用的编程范式,如procedural programming、functional programming、generic programming,以及object-oriented programming。其中object-oriented programming(面向对象编程)无疑是使用最为广泛和重要的范例。下面的两个小技巧将帮助你更好的应用面向对象的设计和实现。首先,我将解释一下虚析构函数在类继承中的重要性。另外一个小技巧将阐述如何去处理嵌套类:将嵌套类声明为其包含类的友元。

 

技巧12:为什么没有虚析构函数的类继承是危险的?

如果一个类的析构函数是非虚的,那么就意味着它不会作为基类来使用(这种类就是我们所熟知的“实体类”)。std::string,std::complex,以及std::vector都是实体类。为什么不推荐继承这些类呢?当你使用公共继承时,你就会在基类与派生类之间创建一种is-a的关系。因此,基类的指针和引用实际上可以指向一个派生的对象。由于析构函数不是虚的,所以当您删除这样一个对象时,C++将不会调用整个析构链。例如:

  
    
class A
{
public :
~ A() // non virtual
{
// ...
}
};

class B: public A /* 不好; A 没有虚析构函数 */
{
public :
~ B()
{
// ...
}
};

int main()
{
A
* p = new B; /* 貌似没什么问题 */
delete p;
/* 问题出现, B的析构未被调用 */
}

  没有调用对象的析构所带来的结果是不确定的。因此,你不应该公开继承这样的类。尤其是,不要继承STL容器和std::string。

 

技巧13:将嵌套类声明为其包含类的友元

  当作为其包含类的友元来声明一个嵌套类时,你应当将友元声明放于嵌套类声明的后面,而不是前面:

  
    
class A
{
private :
int i;
public :
class B /* 先定义嵌套类 */
{
public :
B(A
& a) { a.i = 0 ;};
};
friend
class B; /* 友元声明 */
};

  如果你把友元声明放置于嵌套类声明之前,编译器将丢弃友元声明,因为编译器还没有见过它,不知道它是什么玩意儿。

 

注:关于嵌套类定义

A nested class is any class whose declaration occurs within the body of another class or interface. A top level class is a class that is not a nested class.

一个 class A 如果定义在了另一个 class B 或 interface B 里,那么这个 class A 就是 nested class,class B 或 interface B 则被称为 enclosing class。至于 class A 是定义在了 class B 或 interface B 的什么地方,例如 method 和 constructor,则是没有限制的。

 

 

// 续 任何时候都适用的20个C++技巧 <14-20>  STL and Generic Programming

 

作者: 凌云健笔

出处:http://www.cnblogs.com/lijian2010/

版权:本文版权归作者和博客园共有
转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】
要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任

你可能感兴趣的:(object)