Как исправить пустой вывод при попытке отобразить массив строковых объектов через перегруженный и шаблонный оператор вставки? - PullRequest
1 голос
/ 02 марта 2020

Я объявил container<std::string> c1; в main() для хранения строковых объектов из 10 элементов, т.е. aa bb cc dd . . . jj; но когда я компилирую код, вывод будет пустым. Если я поменяю тип в этих angular скобках на char и использую одну букву, он работает нормально. Я думаю, что что-то не так с тем, что передается в параметрах для перегруженного оператора вставки. Я попытался добавить const и задать один из параметров container<T2> const &cobj - это не помогло решить проблему.

#include <iostream>
#include <string>

template<typename T>
class container
{
    template <typename T2>
    friend std::ostream& operator<<(std::ostream& out, container<T2> &cobj);
    // Postcondition: display the contents of container object cobj in the format shown in the below sample outputs
public:
    container();
    // Postcondition: data member n is initialized to -1 and all elements in the empty arr array are initialized to zero
    bool isEmpty();
    // Postcondition: returns true if nothing is stored in the container; returns false otherwise
    bool isFull();
    // Postcondition: returns true if the container object (i.e., the arr array) is full; returns false otherwise
    int size() const;
    // Postcondition: returns the “size” which is the actual number of elements currently stored in the containe robject; size <= capacity
    int capacity();
    // Postcondition: returns the storage capacity of the container. 
    bool insertBack(const T& val);
    //  Precondition: the container object is not full
    // Postcondition: if arr array is not full, n is incremented by 1; returns true with val is inserted at the end of the arr array 
    //                 Otherwise, returns false; the value is not inserted and program execution continues.

private:
    static const int CAPACITY = 10;     // physical size of the arr array or the storage capacity of a container object
    T arr[CAPACITY];            // arr array can store up to CAPACITY  (10 in our case) elements of any type 
    int n;                      // n is used as the subscript for the arr array. n is initialized to -1 for an empty array
                                // Each time a new value is inserted into the arr array, n must first be incremented 
                                // by 1. Since n has been initialized to -1, the first inserted value is stored in arr[0],
                                // and the 2nd inserted value will be in arr[1], etc.  and the nth inserted value will be 
                                // stored in arr[n – 1]. Obviously, n + 1 represents the actual number of elements
                                // stored in the array after n rounds of insertion.         
};

template<typename T2>
std::ostream& operator<<(std::ostream& out, container<T2> &cobj)
{
    std::cout << "Container storage capacity = " << cobj.capacity() << std::endl
        << "Currently, container contains " << cobj.size() << " elements." << std::endl
        << "The contents of the container:" << std::endl;

    static int funcCalls = 0; // A variable that collects the calls made to this function.
                              // The first call is needed to later output an unique string.
    funcCalls++;

    if (cobj.isEmpty() && funcCalls == 1)
    {
        std::cout << "*** Container is currently empty!" << std::endl << std::endl
            << "The container object is empty!" << std::endl
            << "Currently, the container object contains " << cobj.size() << " element(s) or value(s)";
    }
    else if (cobj.isEmpty())
    {
        std::cout << "*** Container is currently empty!";
    }
    else
    {
        for (int i = 0; i < cobj.size(); ++i)
        {
            std::cout << cobj.arr[i] << ' ';
        }
    }

    std::cout << std::endl << std::endl;

    return out;
}

template<typename T>
container<T>::container()
{
    n = 0;
    arr[CAPACITY] = {0};
}

template<typename T>
bool container<T>::isEmpty()
{
    return n == 0;
}

template<typename T>
bool container<T>::isFull()
{
    return n == CAPACITY - 1;
}

template<typename T>
int container<T>::capacity()
{
    return CAPACITY;
}

template<typename T>
int container<T>::size() const
{
    return n;
}

template<typename T>
bool container<T>::insertBack(const T& val)
{
    if (!isFull())
    {
        n++;
        arr[n - 1] = val;
        return 1;
    }
    else
    {
        return 0;
    }
}

int main()
{
    container<std::string> c1;

    std::cout << "We now insert 10 values at the back of the array one at a time:" << std::endl;    

    c1.insertBack("aa");
    c1.insertBack("bb");
    c1.insertBack("cc");
    c1.insertBack("dd");
    c1.insertBack("ee");
    c1.insertBack("ff");
    c1.insertBack("gg");
    c1.insertBack("hh");
    c1.insertBack("ii");
    c1.insertBack("jj");
    std::cout << c1;

}

1 Ответ

0 голосов
/ 02 марта 2020

В конструкторе по умолчанию

template<typename T>
container<T>::container()
{
    n = 0;
    arr[CAPACITY] = {0};
}

вы пытаетесь инициализировать несуществующий элемент массива с индексом CAPACITY. В результате ваша программа имеет неопределенное поведение,

На самом деле нет необходимости инициализировать массив. Он будет инициализирован по умолчанию.

template<typename T>
container<T>::container() : n( 0 )
{
}

Все эти функции, isEmpry, isFull, емкость и размер должны быть объявлены с квалификатором const.

Функция isFull имеет логическую ошибку , Контейнер будет заполнен, когда его размер будет равен его вместимости

template<typename T>
bool container<T>::isFull() const 
{
    return n == CAPACITY;
}

Функция Friend может быть не шаблонной функцией, определенной в определении класса, например

template<typename T>
class container
{
    friend std::ostream& operator<<(std::ostream& out, const container<T> &cobj)
    {
        //...
    }
    //...

Если вы сделайте все эти изменения, тогда вывод программы будет

We now insert 10 values at the back of the array one at a time:
Container storage capacity = 10
Currently, container contains 10 elements.
The contents of the container:
aa bb cc dd ee ff gg hh ii jj 
...