简体   繁体   中英

Template array class of pointers


I encountered an issue that I have been trying to solve for some time, and simply couldn't do it. Here is the scenario:
1) I have an Template array class that look something like this

//code taken from http://www.learncpp.com, much appreciation for Alex
#ifndef ARRAY_H
#define ARRAY_H 
#include <assert.h> // for assert()
template <typename T>
class Array {
private:
    int m_nLength;
    T *m_ptData;
public:  
    Array() {
        m_nLength = 0;
        m_ptData = 0;
    }
    Array(int nLength) {
        m_ptData= new T[nLength];
        m_nLength = nLength;
    }

    ~Array() {
        delete[] m_ptData;
    }

    void Erase() {
        delete[] m_ptData;
        m_ptData= 0;
        m_nLength = 0;
    }

    T& operator[](int nIndex) {
        assert(nIndex >= 0 && nIndex < m_nLength);
        return m_ptData[nIndex];
    }

    int GetLength() { return m_nLength; }
    friend ostream& operator<<(ostream& out, const Array<T>& n) {
    for(int i=0; i<n.m_nLength; i++) {
            if(i) it << "\n";
            it << n[i];
        }
        return it;
    } 

};

#endif

2) And this is the class I tried making array of and how I did it (it has dynamic memory allocation)

class Tune {
    char* artist;
    char* song;
public:
    explicit Tune(const char* a, const char* s) {
        artist = new char [strlen(a)+1]; strcpy(artist, a);
    song = new char [strlen(s)+1]; strcpy(song, s);     
}
...

#include "Array.h"    
void main() {
    Array<Tune> tunes(5);          //Array of 5 elements
}


error C2512: 'Tune' : no appropriate default constructor available
1>          c:\x\x\x\visual studio 2010\projects\x\x\array.h(26) : while
compiling class template member function 'Array<T>::Array(int)'
1>          with
1>          [
1>              T=Tune
1>          ]
1>          c:\x\x\x\visual studio 2010\projects\x\x\main.cpp(10) : see reference to
class template instantiation 'Array<T>' being compiled
1>          with
1>          [
1>              T=Tune
1>          ]

3) Then I remembered that I could solve that issue with something like this (without using my array template class):

void main() {
    Tune **tunes = new Tune*[5];
    ...
}

I would like to know is this the solution and how do I create Array of pointers using my template array class, and second (lest say I have overriden operator<<), how to I print one or all of the elements of the array.
The full program is huge, this is the piece of it. Most of the code is under comments, so the issue is isolated.
I am pretty stuck and this project means a lot to me, but I am an inexperienced programmer so I find it hard to handle issue like this. Thanks for help in advance.
Cheers!

First of all please show the full error message . Secondly it is not clear what is MyType and whether it has the default constructor.

If MyType is for example some arithmetic type then the code below will be compiled without errors.

#include "Array.h"    

int main() {
    Array<MyType> data(5);          //Array of 5 elements
}

At least class Array has the default constructor though it is not used. As for the type MyType then it can be said nothing because you did not show neither the full error message nor the definition of MyType. I suggest to check whether MyType has the default constructor.

If you want to create an array of pointers then you should write

Array<MyType *> data(5);          

As for this code

void main() {
    MyType **data = new MyType*[5];
    ...
}

then it has nothing common with the problem. Take into account that main shall be defined as having return type int.

EDIT: If do not take into account errors in the definition of class Tune, then it has no default constructor. So you should decide whether you want to create an array of obects of type Tune or an array of pointers to objects of type Tune. I already showed how fo define the array of pointers. Or define the default constructor for class Tune.

How do I create an array of pointers using my template Array class?

If your class needs an alternate way of constructing its elements, you should create another constructor that initializes it the way you wish, similar to std::vector 's constructor:

Array( int count, const T& value );

The easiest way to implement this would be to declare m_ptData as a double pointer and initialize it like so:

Array( int count, const T& value ) : m_ptData(new T*[count])
{
    for (int i = 0; i < count; ++i)
    {
        m_ptData[i] = new T(value);
    }
}

The best (and most difficult) way would be to use placement-new to initialize it, this is how std::vector does it. You can use it like this:

int main()
{
    Array<MyType> data(5, MyType("abc")); // Array of 5 elements,
                                          // all initialized to MyType("abc")
}

How do I print one or all of the elements of the array?

The inserter operator<<() should be used to print the entire array, so making it do something like printing only some of the elements would be a bit confusing to maintainers of your code. As alternatives, you can create a stream manipulator if you wish to customize output, or you can use a member function that takes a count of the numbers you would like to print. Also, your class can have begin() and end() functions which return pointers to the beginning and end of the array, so the user of the class can implement the printing at their discretion. In either cases, looping should be used to print the elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM