【问题标题】:derived class calls wrong base class constructor [duplicate]派生类调用错误的基类构造函数[重复]
【发布时间】:2013-03-14 11:13:09
【问题描述】:

你能解释一下下面代码的输出吗?我需要怎么做才能调用正确的基类构造函数?

谢谢。

#include <vector>
#include <iostream>

template <class CONTAINER> class SequenceComposite {
protected:
    CONTAINER m_data;
public:
    typedef typename CONTAINER::value_type value_type;
    typedef typename CONTAINER::allocator_type allocator_type;
    typedef typename CONTAINER::size_type size_type;
    explicit SequenceComposite(const allocator_type& alloc = allocator_type()) : m_data(alloc) {
        std::cout << std::endl << "SequenceComposite(alloc)" << std::endl;
    }
    explicit SequenceComposite(size_type n, const value_type& val = value_type(),
        const allocator_type& alloc = allocator_type()) : m_data(n, val, alloc) {
        std::cout << std::endl << "SequenceComposite(n, val, alloc)" << std::endl;
    }
    SequenceComposite(const SequenceComposite& x) : m_data(x.m_data) {
        std::cout << std::endl << "SequenceComposite(x)" << std::endl;
    }

};

template <class DTYPE>
class VectorComposite : public virtual SequenceComposite< std::vector<DTYPE> > {
public:
    typedef typename VectorComposite::value_type value_type;
    typedef typename VectorComposite::allocator_type allocator_type;
    typedef typename VectorComposite::size_type size_type;
    explicit VectorComposite(const allocator_type& alloc = allocator_type()) : SequenceComposite< std::vector<DTYPE> >(alloc) {
        std::cout << "VectorComposite(alloc)" << std::endl;
    }
    explicit VectorComposite(size_type n, const value_type& val = value_type(),
        const allocator_type& alloc = allocator_type()) : SequenceComposite< std::vector<DTYPE> >(n, val, alloc) {
        std::cout << "VectorComposite(n, val, alloc)" << std::endl;
    }
    VectorComposite(const VectorComposite& x) : SequenceComposite< std::vector<DTYPE> >(x) {
        std::cout << "VectorComposite(x)" << std::endl;
    }

};

template<typename T> class MyModel : public virtual VectorComposite<T> {
    public:
        MyModel() {
            std::cout << "MyModel()" << std::endl;
        };
        MyModel(const MyModel<T> &vec) : VectorComposite<T>(vec) {
            std::cout << "MyModel(x)" << std::endl;
        }
        MyModel( size_t n, const T& value= 0) : VectorComposite<T>(n, value) {
            std::cout << "MyModel(n, val)" << std::endl;
        }
};

int main() {
    MyModel<float> c(4, 2.0);
    MyModel<float> e(c);

    VectorComposite<float> a(3, 2.0);
    VectorComposite<float> b(c);

    return 0;
}

输出:

SequenceComposite(alloc)
VectorComposite(n, val, alloc)
MyModel(n, val)

SequenceComposite(alloc)
VectorComposite(x)
MyModel(x)

SequenceComposite(n, val, alloc)
VectorComposite(n, val, alloc)

SequenceComposite(x)
VectorComposite(x)

我期待

SequenceComposite(n, val, alloc)
VectorComposite(n, val, alloc)
MyModel(n, val)

SequenceComposite(x)
VectorComposite(x)
MyModel(x)
...

【问题讨论】:

  • 为什么还要使用virtual继承?
  • @PeterWood:虽然我同意应明确说明预期结果,但不难看出,例如在第一种情况下,似乎调用了“错误的”SequenceComposite 构造函数。
  • @Jon 我们都有不同的回复方式。我想改进问题,不一定要回答。
  • @Michael:您不会扩展典型意义上的 an 接口,因为您的基类具有成员变量(甚至可能是非纯虚拟成员函数?)。典型意义上的接口是一个基类,它只描述接口(很明显)而不包含任何实现细节。在这种情况下,virtual 继承对于避免diamond inheritance problem 很有用。除非您的班级有遇到该问题的风险,否则没有理由使用 virtual 继承

标签: c++ templates inheritance constructor


【解决方案1】:

虚拟基类从最派生类型的构造函数初始化。所以在前两个例子中,SequenceComposite 的默认构造函数被调用。那是一个带有默认参数的allocator_type。要使用不同的构造函数,请从派生最多的类型的初始值设定项列表中调用它。

【讨论】:

    猜你喜欢
    • 2016-07-19
    • 2018-07-16
    • 2018-07-21
    • 1970-01-01
    • 2015-08-18
    • 2020-09-22
    • 2011-05-03
    • 2011-02-02
    • 2011-09-27
    相关资源
    最近更新 更多