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

Unexpected Constructor called in class

本文关键字:构造函数 意外 调用      更新时间:2023-10-16

有一些类: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(s组成。似乎在函数中调用了默认构造函数,并将其传递给Array4。在运算符之后,Array1和Array2仍然是数字0-9

以下是阵列的相关代码

模板类数组{

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];   
}

不确定是否提供了足够的信息。任何提示都将不胜感激。

当基类是(依赖(类模板时,访问基类数据成员的最简单方法是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_

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

问题是:NumericArrayArray都有

T* m_data;
int size;

函数Array::operator[]是从使用Array::m_dataArray调用的,但是NumericArray::operator*设置NumericAray::m_data。它可能如你所期望的那样工作,但你读错了指针。

NumericArray中删除成员,并使成员成为protected,而不是Array中的private。如果实现稍微改变一点,那么第二部分是可选的。