|
发表于 2020-1-26 15:09:01
|
显示全部楼层
这是动态多态的例子
#include<iostream>
#include<vector>
using namespace std;
class DeA
{
public:
void doSomething() const { cout<<"DeA"<<endl; }
};
class DeB
{
public:
void doSomething() const { cout<<"DeB"<<endl; }
};
template<typename T>
void DoSomething(vector<T> vec)
{
for(vector<T>::iterator iter = vec.begin();
iter != vec.end();
++iter)
{
iter->doSomething();
}
}
int main()
{
typedef vector<DeA> DEAVEC;
typedef vector<DeB> DEBVEC;
DEAVEC va;
DEBVEC vb;
va.push_back(DeA());
va.push_back(DeA());
vb.push_back(DeB());
vb.push_back(DeB());
DoSomething(va);
DoSomething(vb);
}
这是静态多态的例子
个人觉得,使用动态多态处理异质对象集合上更自然一些。
首先从概念上将,调用doSomething职责是IBASE(IBASE才知道到底做什么事,而上面的方法打破了这个封装关系),为了处理不同的对象必须分别为这些对象建立一个vector来保存。而处理异质对象集合正是构建系统经常要做的事。
呵呵写着,写着发现很难自圆其说了:)
GP对类型解耦,是比OO更高层次的抽象
--------------------------------------------------------
刚才写着代码,渐渐明白了。这是很有道理的。比如说有一个人类,和一个狗类,他们都有吃饭的动作。如果为了处理这个动作就为他们引入一个动物的基类,那的确感觉增加了耦合性,仅仅为了一个行为相同就增加一个基类显然得不尝失。而把这些行为抽象出来也许更好一些。(万一将来要处理食虫草这种生物,
就可以直接重用代码了,不用再引入一个不伦不类的基类:) )
看来自己的信念开始动摇了。
你说GP象小型的framework,我也不太同意,我觉得GP更象是非常独立的“组件
-----------------------------------------------------------------------------------------------------------
这里比如要自己做一个可以使用STL算法的容器,那么设计它的迭代器的时候必须提供一些traits才行,
感觉这点和framework有一点相似之处。但又有很大不太,所以想把GP比喻成小型的framework感觉又有点不贴切。
std::string的设计不是有大牛说它太胖了吗?
---------------------------------------------------------------------------------------------------------
好像是Herb Sutter说的, Scott Meyer 也说过在适当的时候应该把可重用的函数从成员函数中独立出来。
我也同意这个观点,这也是我不喜欢纯OO的原因:)
丙:
面向对象和泛型编程都追求[复用]之美,[复用]是软件工程的灵魂。
但是,它们[复用]的方式又有所不同:面向对象侧重于二进制级别的[复用],泛型侧重于源代码级别的[复用]。
所谓优秀的程序库,是为了被工程所用而存在;所谓优秀的工程,是以优美地[复用]程序库而著称。我认为,工程和程序库之间的差别并没有想象中的那么大,而是用[模糊]来形容很是恰当。
设想有很多工程,它们都优雅地运用了某个程序库一个组件来完成一个特定的功能,那么[将这个功能提取出来做成一个组件]是在合理不过的事情了。所以我说,工程与程序库之间并没有严格的界限。
乙:
其实静态多态可以这样:
#include <iostream>
#include <vector>
using namespace std;
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
using namespace boost;
#define foreach BOOST_FOREACH
class DeA
{
public:
void xxx() const { cout << "DeA" << endl; }
};
class DeB
{
public:
void yyy() const { cout << "DeB" << endl; }
};
class dosomething_visitor : public static_visitor<>
{
public:
void operator()(DeA const & dea) const
{
dea.xxx();
}
void operator()(DeB const & deb) const
{
deb.yyy();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
typedef variant< DeA, DeB > de_t;
typedef vector< de_t > devec_t;
devec_t vec;
vec.push_back( DeA() );
vec.push_back( DeB() );
foreach( de_t const & de, vec )
{
apply_visitor( dosomething_visitor(), de );
}
return 0;
}
很优雅是吧?:) |
|