c++接口类的实现
来源:互联网 发布:你最努力的时候知乎 编辑:程序博客网 时间:2024/04/29 19:32
c++不像java一样有纯接口类的的语法,但我们可以通过一些手段实现相同的功能。
一:
考虑这样的代码:
class A
{
protected:
virtual ~A()
{
cout << __FUNCTION__ << endl;
}
};
class B : public A
{
public:
virtual ~B()
{
cout << __FUNCTION__ << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A* p1 = new A; //[1]有问题
delete p1;
B* p2 = new B;
delete p2; //[2]没问题的
A* p3 = new B;
delete p3; //[3] 有问题
return 0;
}
通过在类中,将类的构造函数或者析构函数申明成protected ,可以有效防止类被实例话,要说实用的话,构造函数是protected更有用,肯定能保证类不会被实例化,而如果析构函数是protected的话,构造函数不是protected的话,还可能存在编译通过的漏洞,如下:
A:
class A
{
protected:
A()
{
cout << __FUNCTION__ << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A* p1 = new A; //编译不通过,无法访问protected构造函数
delete p1;
return 0;
}
B:
class A
{
protected:
~A()
{
cout << __FUNCTION__ << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A* p1 = new A; //编译通过,此时因为仅仅是用到了A的构造函数,还不需要它的析构函数
return 0;
}
C:
class A
{
protected:
~A()
{
cout << __FUNCTION__ << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A* p1 = new A;
delete p1; //编译失败,因为编译器发现A的析构函数是protected
return 0;
}
所以,一种可行的办法貌似是这样的:
class A
{
protected:
virtual ~A()
{
cout << __FUNCTION__ << endl;
}
};
class B : public A
{
};
int _tmain(int argc, _TCHAR* argv[])
{
B* p =new B; //这种情况下确实是可行的
delete p;
return 0;
}
由于B public继承自A,所以其可以完全访问A的构造或析构函数,但是:
int _tmain(int argc, _TCHAR* argv[])
{
A* p =new B;
delete p; //由于p变成指向A的指针,字面上编译器需要知道A的析构函数,然后A的析构函数又是protected
return 0;
}
即便像这样B显示重载了A的析构函数:
class A
{
protected:
virtual ~A()
{
cout << __FUNCTION__ << endl;
}
};
class B : public A
{
public:
virtual ~B()
{
cout << __FUNCTION__ << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A* p =new B;
delete p; //也还是不行,因为重载是运行时的事情,在编译时编译器就认定了A的析构函数,结果无法获取
return 0
}
小结:
貌似用protected这样的方法并不是很恰当,虽然在遵守一定规则的情况下确实有他的实用价值,但并不是很通用。
二:
其实上面protected的思路是对的,无非是让父类无法实例化,那么为了让父类无法实例化,其实还有一个方法,使用纯虚函数。
class A
{
public: //这里就不用protected了
virtual ~A() = 0;
};
class B : public A
{
};
int _tmain(int argc, _TCHAR* argv[])
{
B* p =new B;
delete p;
return 0;
}
这样写貌似不错,以往大家都把类中的一般成员函数写成纯虚的,这次将析构函数写成纯虚的,更加增加通用性,编译也通过了,但就是在链接的时候出问题,报错说找不到A的析构函数的实现,很显然吗,因为A的析构是纯虚的吗。
class A
{
public: //这里就不用protected了
virtual ~A() = 0 //它虽然是个纯虚函数,但是默认实现,可以有
{ //这个语法很好很强大,经过小强的指点终于高清了他的用法(完全是为了实现其接口类而弄的语法吧)
cout << __FUNCTION__ << endl;
}
};
class B : public A
{
};
int _tmain(int argc, _TCHAR* argv[])
{
B* p =new B;
delete p;
A* p2 =new B;
delete p2; //不用担心编译器报错了,因为此时A的析构函数是public
return 0;
}
如此终于大功告成了,注意,不能将构造函数替代上面的析构函数的用法,因为构造函数是不允许作为虚函数的。
补充:以上那个语法就真的只是为了这种情况而存在的,因为一般我们在虚类中申明的接口:
virtual foo() = 0;
virtual foo() = 0 {}
这两种写法是完全没有区别的,纯虚函数的默认实现,仅仅在它是析构函数中才有意义!!!
所以可以说,老外是完全为了这一个目的而发明了这种语法...
最终的接口类
class Interface
{
public:
virtual ~Interface() = 0 {}
};
应该挺完美的了吧,hiahia
- <C++> 类的‘’实现‘’与‘’接口‘’分离
- C++—String类接口的实现
- C#——找出实现某个接口的所有类
- C 链表及其接口的实现
- C的字符串操作接口实现
- "rpm -qa" C 接口的实现过程
- C#&&UnityEngine:Intelface接口的简单实现
- 类、接口继承以及接口的实现
- C++“隐藏实现,开放接口”的实现方案
- Objective-C类-Objective-C 分离 接口和实现文件
- 实现接口的类是否继承接口实现的问题
- c++接口类的实现
- 接口实现类的问题
- c++接口类的实现
- c++类接口的实现
- 实现接口的枚举类
- Map接口的实现类
- Set接口的实现类
- 【分享】January 2013 - Mobile Shopping (omnibus)(2013一月份移动购物 (omnibus))
- php 断点调试工具配置之三
- Oracle的Move操作
- Android PackageInstaller 静默安装的实现(附源码)
- hdu 3549 Flow Problem (ek算法模板)
- c++接口类的实现
- TCP与UDP的区别
- PMP Related Topic 6
- Openssl有关大数运算函数介绍
- js每个5分钟执行一次ajax请求
- JQuery - 点击浏览器后退键时发出警告
- 网站开发积累(对MVC设计模式的理解)
- spring 配置、架构
- php 断点调试工具配置之故障排除