在类中调用了意外的构造函数

时间:2014-07-29 14:54:34

标签: c++

有一些类:Array,NumericArray。 Array是一个模板类,NumericArray是一个继承自Array的类,用于获取int,double等。

NumericArray标题的一部分:

template <class T = int> 
class NumericArray : public Array<T>{
    private:
        T* m_data;
        int size;

    public:

        NumericArray<T> operator * (T factor)const;

};

这里是NumericArray的构造函数和一些函数:

template <class T>
NumericArray<T>::NumericArray(){
    m_data = new T[10];
    size = 10;
}

template <class T>
NumericArray<T>::NumericArray(int n){
    m_data = new T[n];
    size = n;
}

template <class T>
NumericArray<T>::NumericArray(const NumericArray<T>& s_data){
    m_data = new T[s_data.size];
    // assign elements in the source array
    for (int i = 0;i<=(s_data.Size()-1 ); i++){
        m_data[i] = s_data.m_data[i];
    }
    size = s_data.Size();
}

/*  Destructor  */
template <class T>
NumericArray<T>::~NumericArray(){
    delete [] m_data;
}

template <class T>
NumericArray<T> NumericArray<T>::operator * (T factor)const{
    NumericArray<T> temp(size);
    for (int i = 0; i<size;i++){
        temp.m_data[i] = (*this)[i] *factor;
    }
    return temp;
}

当我在main()中调用它时,会发生奇怪的事情。例如:

NumericArray<int> intArray1(10);
NumericArray<int> intArray2;
for(int i =0; i<10;i++){
    intArray1[i] = i;
    intArray2[i] = i;
}   

2个数组确实包含数字0-9,但如果我打电话     NumericArray intArray4 = intArray1 * 2;

intArray4由零(0)组成。似乎在函数中调用默认构造函数并将其传递给Array4。在运算符之后,Array1和Array2仍为数字0-9

以下是Array

的相关代码

模板类Array {

private:
    T* m_data;
    int size;

public:
    Array();    // constructor
    Array(int n);   // constructor
    Array(const Array<T>& s_data);  //Copy Constructor

    virtual ~Array();   // destructor

    void SetElement(int i, const T& source);
    T& GetElement(int i)const;
    int Size() const;
    int DefaultSize()const;
    void DefaultSize(int n);

    // Operator overloading
    Array<T>& operator = (const Array<T>& source) ;
    T& operator [](int i);
    const T& operator [] (int i) const;
};



template <class T>
Array<T>::Array(){
    //  default constructor
    m_data = new T[defaultSize];    // initialize T*
    size = defaultSize;             // initialize integer
}

template <class T>
Array<T>::Array(int n){
    // Constructor with arguments
    m_data = new T[n];
    size = n;
}

template <class T>
Array<T>::Array(const Array<T>& s_data){
    // Copy constructor
    m_data = new T[s_data.Size()];
    // assign elements in the source array
    for (int i = 0;i<=(s_data.Size()-1 ); i++){
        m_data[i] = T( s_data.m_data[i]);
    }
    size = s_data.Size();
    defaultSize = s_data.Size();
}

template <class T>
T& Array<T>::operator [](int i) {
    if (i > size|| i<0){
        OutOfBoundsException a;
        throw a;
    }
    return m_data[i];   
}

不确定是否提供了足够的信息。任何提示都非常感谢。

2 个答案:

答案 0 :(得分:0)

问题在于:NumericArrayArray都有

T* m_data;
int size;

函数Array::operator[]从使用Array的{​​{1}}调用,但Array::m_data设置NumericArray::operator*。它可能正如您所期望的那样工作,但您正在从错误的指针读取。

NumericAray::m_data移除成员,并在NumericArray中将成员protected代替private。如果实现稍微改变,第二部分是可选的。

答案 1 :(得分:0)

当基类是(依赖的)类模板时,访问基类数据成员的最简单方法是using声明,如下所示:

#include <iostream>
using namespace std;

template< class Item >
class Base
{
protected:
    Item    item_;

    Base( Item const& v ): item_( v ) {}
};

template< class Item >
class Derived
    : public Base< Item >
{
protected:
    using Base<Item>::item_;

public:
    auto value() const -> Item { return item_; }
    Derived( Item const& v ): Base<Item>( v ) {}
};

auto main() -> int
{
    Derived<int> const x( 42 );
    cout << x.value() << endl;
}

或者,您可以限定访问权限,例如: this->item_Base<Item>::item_

也就是说,让派生类直接访问基类数据成员通常不是一个好主意。