C++界面风格编程。需要一条出路

发布于 2024-10-22 20:24:09 字数 1553 浏览 4 评论 0原文

template <typename T>
class BaseQueue
{
    public :
    virtual void push_back(T value) = 0;
    //other  virtual methods
};

template <typename T>
class BaseDeque: public virtual BaseQueue<T>
{
    public:
        virtual void push_front(T value) = 0;
        //other virtual methods
};

//Realisation
template <typename T>
class VectorQueue: public BaseQueue<T>
{
    typedef typename std::vector<T> array;
    private: array adata;
    public:
    VectorQueue()
    {
       adata = array();
    }

    void push_back(T value)
    {
        adata.push_back(value);
    }
};

template <typename T>
class VectorDeque: virtual public VectorQueue<T>, virtual protected BaseDeque<T>//, 
{
    void push_front(T value)
    {
        VectorQueue::adata.push_front(value);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    VectorDeque<int> vd = VectorDeque<int>();//here is a error

    int i;
    std::cin >> i;
    return 0;
}

我有这样的错误:“C2259:'VectorDeque':无法实例化抽象类...”。我该如何修复它? VectorQueue类已经实现了BaseQueue类的每一个虚方法。但编译器不知道。我看到的唯一方法就是写这样的东西:

template <typename T>
class VectorDeque: virtual public VectorQueue<T>, virtual protected BaseDeque<T>//, 
{
    void push_front(T value)
    {
        VectorQueue::adata.push_front(value);
    }
    void push_back(T value)
    {
        VectorQueue::push_back(value);
    }
    //repeat it fo every virtual method of BaseQueue class (interface)
};

但这太糟糕了。

template <typename T>
class BaseQueue
{
    public :
    virtual void push_back(T value) = 0;
    //other  virtual methods
};

template <typename T>
class BaseDeque: public virtual BaseQueue<T>
{
    public:
        virtual void push_front(T value) = 0;
        //other virtual methods
};

//Realisation
template <typename T>
class VectorQueue: public BaseQueue<T>
{
    typedef typename std::vector<T> array;
    private: array adata;
    public:
    VectorQueue()
    {
       adata = array();
    }

    void push_back(T value)
    {
        adata.push_back(value);
    }
};

template <typename T>
class VectorDeque: virtual public VectorQueue<T>, virtual protected BaseDeque<T>//, 
{
    void push_front(T value)
    {
        VectorQueue::adata.push_front(value);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    VectorDeque<int> vd = VectorDeque<int>();//here is a error

    int i;
    std::cin >> i;
    return 0;
}

I have such error: "C2259: 'VectorDeque' : cannot instantiate abstract class ...". How can I fix it? Class VectorQueue has realize every virtual method of BaseQueue class already. But the compiler doesn't know it. The only way I see is to write something like this:

template <typename T>
class VectorDeque: virtual public VectorQueue<T>, virtual protected BaseDeque<T>//, 
{
    void push_front(T value)
    {
        VectorQueue::adata.push_front(value);
    }
    void push_back(T value)
    {
        VectorQueue::push_back(value);
    }
    //repeat it fo every virtual method of BaseQueue class (interface)
};

But it's awful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

§普罗旺斯的薰衣草 2024-10-29 20:24:09

BaseQueue 中的 push_back 并未在继承链的 BaseDeque 端实现,因此最子级的类仍然是抽象的。

我认为你试图在这里强行建立不应该存在的阶级关系。请注意,在标准库中,dequevector 是不同的容器类型,而 queue 等内容如何使这些容器适应非常精确的接口,而不是尝试继承。

push_back from BaseQueue isn't implemented on the BaseDeque side of the inheritance chain, and thus the childmost class is still abstract.

I think you're trying to force a class relationship here that shouldn't exist. Note how in the standard library deque and vector are distinct container types and things like queue adapt those containers to very precise interfaces rather than trying to inherit.

溺ぐ爱和你が 2024-10-29 20:24:09

即使您解决了钻石问题(或遵循@Mark B 的建议并将它们分开),您还会遇到一些其他问题:

template <typename T>
class VectorQueue: public BaseQueue<T>
{
    typedef typename std::vector<T> array;
    private: array adata;   // if this is private, VectorDeque can't reach it

    public:
    // constructors have an initializer section
    // member variables should be initialized there, not in the body
    VectorQueue()
    // : adata()  // however, no need to explicitly call default constructor
    {
       // adata = array();
    }
};


template <typename T>
class VectorDeque: virtual public VectorQueue<T>, virtual protected BaseDeque<T>
{
    void push_front(T value)
    {
        // if adata is protected, you can just access it.  No need for scoping
        /*VectorQueue::*/  adata.push_front(value);
        // Error:  std::vector doesn't have a method push_front.
        // Perhaps you meant to use std::list?
    }
};

Even if you solve your diamond issue (or follow @Mark B's advice and keep them separate), you have a few other issues in there:

template <typename T>
class VectorQueue: public BaseQueue<T>
{
    typedef typename std::vector<T> array;
    private: array adata;   // if this is private, VectorDeque can't reach it

    public:
    // constructors have an initializer section
    // member variables should be initialized there, not in the body
    VectorQueue()
    // : adata()  // however, no need to explicitly call default constructor
    {
       // adata = array();
    }
};


template <typename T>
class VectorDeque: virtual public VectorQueue<T>, virtual protected BaseDeque<T>
{
    void push_front(T value)
    {
        // if adata is protected, you can just access it.  No need for scoping
        /*VectorQueue::*/  adata.push_front(value);
        // Error:  std::vector doesn't have a method push_front.
        // Perhaps you meant to use std::list?
    }
};
北音执念 2024-10-29 20:24:09

多重继承和静态多态性很有帮助,例如:

// Abstract bases
template <typename T, typename Val> 
class BaseQueue 
{     
public :     
    void push_back(Val val)
    {
        static_cast<T*>(this)->push_back(val); 
    }
    // ...
};  
template <typename T, typename Val> 
class BaseDeque
{     
public:         
    void push_front(Val val)
    {
        static_cast<T*>(this)->push_front(val); 
    }
    // ...
};

// Concrete class
#include <deque>
template <typename Val> 
class QueueDeque: 
    public BaseQueue<QueueDeque<Val>, Val>,
    public BaseDeque<QueueDeque<Val>, Val>
{   
    std::deque<Val> vals;
public:
    void push_front(Val val)
    {
        vals.push_front(val); 
    }
    void push_back(Val val)
    {
        vals.push_back(val); 
    }
    // etc..
};  
int main() 
{     
    QueueDeque<int> vd;// no more error      
    vd.push_front(5);
    vd.push_back(0);
    return 0; 
} 

Multiple inheritance and static polymorphism are of help, for instance:

// Abstract bases
template <typename T, typename Val> 
class BaseQueue 
{     
public :     
    void push_back(Val val)
    {
        static_cast<T*>(this)->push_back(val); 
    }
    // ...
};  
template <typename T, typename Val> 
class BaseDeque
{     
public:         
    void push_front(Val val)
    {
        static_cast<T*>(this)->push_front(val); 
    }
    // ...
};

// Concrete class
#include <deque>
template <typename Val> 
class QueueDeque: 
    public BaseQueue<QueueDeque<Val>, Val>,
    public BaseDeque<QueueDeque<Val>, Val>
{   
    std::deque<Val> vals;
public:
    void push_front(Val val)
    {
        vals.push_front(val); 
    }
    void push_back(Val val)
    {
        vals.push_back(val); 
    }
    // etc..
};  
int main() 
{     
    QueueDeque<int> vd;// no more error      
    vd.push_front(5);
    vd.push_back(0);
    return 0; 
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文