| 关键词: nbsp CPU Computer 拷贝 函数 一个 模式 name 就是 BRIDGE |
什么是桥接模式?举个例子:平时我们我们的USB(Universal Serial Bus(通用串行总线)),其实其设计的模式就是桥接模式。桥接模式的作用就是:将抽象部份与它的实现部份分离,使它们都可以独立地变化。也就是说无论USB插的是U盘,还是小风扇。都只是外部的独立变化,电脑内部是不受影响。不扯远了,这里不是主要说桥接模式的用法。下面看看使用桥接模式需要注意一个小小的问题。[cpp] view plaincopy#ifndef BRIDGE_H #define BRIDGE_H #include <stdlib.h> class CPU { public: CPU() { m_name = (char *)malloc(32); }; ~CPU() { free(m_name); }; private: char *m_name; }; class Computer { public: Computer(){}; ~Computer(){}; CPU &GetCPU1(){ return m_cpu; } CPU *GetCPU2(){ return &m_cpu; } private: CPU m_cpu; }; int main() { { Computer computer; { CPU cpu = computer.GetCPU1(); // 运行时报错 } } { Computer computer; { CPU *cpu = computer.GetCPU2(); } } return 0; } #endif 当运行上面的代码时,应该会产生一个错误,因为第一个例子是有误的。因为这涉及到浅拷贝(复制)和深拷贝。首先,我们知道如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数;而这个默认拷贝构造函数就是浅拷贝。而在C++中,在用一个对象初始化另一个对象时,只复制了成员,并没有复制资源,使两个对象同时指向了同一资源的复制方式称为浅复制。也就是说CPU cpu = computer.GetCPU1();中的cpu跟computer中的m_cpu的m_name都是指同一个地址。所以当cpu生命周期结束时,cpu会调用析构函数;当computer生命周期结束时,m_cpu又会调用析构函数,从而导致析构函数会被调用再次,结合上面的例子,也就是m_name会被free了两次。因此会造成程序运行时错误。当然,如果要解决这个问题,就是自定义拷贝构造函数(深拷贝)。[cpp] view plaincopy#ifndef BRIDGE_H #define BRIDGE_H #include <stdlib.h> #include <string.h> class CPU { static const int NAME_LENGTH = 32; public: 声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除 |