0

昨天,我写了一些代码,如果这是好的或坏的做法,我真的很感激。如果它不好,可能会出什么问题。

构造如下:

可悲的是,基类 A 来自 API 作为模板。目标是能够将 A 的派生类放入 std::vector 中。我通过基类 B 实现了这一点,从 A 继承的所有派生类都将从该基类继承。如果没有 B 中的纯虚拟函数,则会调用 A 中的 foo() 函数。

使用 B 中的纯虚拟函数,调用 C 中的 foo() 版本。这正是我想要的。

那么这是不好的做法吗?

编辑:

为了消除我的示例代码中的一些误解:

template <class T> 
class A 
{
public:
    /* ctor & dtor & ... */
    T& getDerived() { return *static_cast<T*>(this); }
    void bar() 
    {
        getDerived().foo(); // say whatever derived class T will say
        foo(); // say chicken
    }
    void foo() { std::cout << "and chicken" << std::endl; }
};

class B : public A<B>
{
public:
    /* ctor & dtor */
    virtual void foo() = 0; // pure-virtual 
};

class C : public B
{
public:
    /* ctor & dtor */
    virtual void foo() { std::cout << "cow"; }
};

class D : public B
{
public:
    /* ctor & dtor */
    virtual void foo() { std::cout << "bull"; }
};

std::vector 应同时包含 C 和 D 和

void main()
{
std::vector<B*> _cows;
_cows.push_back((B*)new C()));
_cows.push_back((B*)new D()));

for(std::vector<B*>::size_type i = 0; i != _cows.size(); ++i)
   _cows[i].bar();

}

带输出

cow and chicken
bull and chicken

是需要的。

据我所知,除了使用基类之外,没有其他方法可以将从模板类派生的类存储在容器中。如果我为派生类使用基类,例如,B 我必须将向量中的每个实例转换回其正确的类。但是在调用 bar() 时,我不知道确切的类型。

4

1 回答 1

0

我把它称为做可能令人困惑和混淆的事情的坏习惯。

1) 所有基类和子类中的函数名都应该是虚拟的或非虚拟的。
在继承层次结构中混合覆盖和重载是一个非常糟糕的主意。
没有人真正期待这样的事情。
因此,如果 A::foo 也应该是虚拟的,或者 B 和 C foo 不应该。

2)最好基类应该是接口。
因此 A:foo 应该是纯虚拟的,而不是 B::foo。
2b) 如果基类已经提供了默认实现,则不要在子类中声明纯虚拟函数。

于 2013-06-11T07:26:37.300 回答