2

So here's my template class declaration:

template <class elemType>
class listType

I have a constructor like this:

listType(const elemType &, const elemType &, const elemType &, 
const elemType &, const elemType &){

list[0] = a;
list[1] = b;
list[2] = c;
list[3] = d;
list[4] = e;

}

With a protected member variable like this:

elemType *list;

This is to pass in objects of type stockType in my code. I inherited a class from this template class listType called stockListType and tried to make a constructor that would pass in the parameters to the already made constructor in listType with this:

stockListType :: stockListType(const stockType &a, const 
stockType &b, const stockType &c, const stockType &d, const 
stockType &e) : listType(a, b, c, d, e) {

}

I'm not sure if I understand how to use class templates and constructors with class templates that I inherited a class from.

I tried making 5 objects of type stockType (inputting their information for their member variables using a file) and then trying to use the constructor of the inherited class with those objects in my main code:

stockListType object(obj1, obj2, obj3, obj4, obj5); 

But I keep getting an error when it tries to run.

EDIT: The error I get is Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

The child class header is:

#ifndef stockListTypeHeader_h
#define stockListTypeHeader_h

#include "listType Header.h"

class stockListType : public listType <class stockType>
{
public:
stockListType(const stockType &, const stockType &, const stockType &, const 
stockType &, const stockType &);

void sortList();
void swap(stockType&, stockType&);

const void printList();

protected:
    stockType *sortIndicesGainLoss;




};


#endif /* stockListTypeHeader_h */

And the .cpp file of the child class is:

#include <stdio.h>
#include "stockListTypeHeader.h"
#include "stockType.h"
#include <iostream>


void stockListType:: sortList(){
    sortIndicesGainLoss = list;

for(int i =0; i<5; i++){
    for(int j =0; j<5-i-1; j++) {
        if (sortIndicesGainLoss[j].getStockSymbol() > 
sortIndicesGainLoss[j+1].getStockSymbol()){
            swap(sortIndicesGainLoss[j], sortIndicesGainLoss[j+1] );
        }
        }
    }
}

void stockListType:: swap(stockType &xp, stockType &yp){
stockType temp = xp;
xp = yp;
yp = temp;

}

 void const stockListType:: printList() {
     for(int i=0; i<5; i++)
         cout << sortIndicesGainLoss[i];

}

 stockListType :: stockListType(const stockType &a, const stockType &b, const 
stockType &c, const stockType &d, const stockType &e) : listType(a, b, c, d, e) 
{

}

EDIT 3:

Thank you all for helping me, I figured out it was because I hadn't initialized list or my sortIndicesGainLoss.

Now I am getting an error under my sortList method. Does anybody have a clue as to why?

Alexandra
  • 125
  • 10
  • 3
    Please read about [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). And of course please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) to show us. Lastly please [learn how to debug your programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Some programmer dude Nov 15 '18 at 08:38
  • 2
    "*But I keep getting an error when it tries to run.*" What error? Please [edit] the question to copy and paste full error message into it. – Yksisarvinen Nov 15 '18 at 08:39
  • show us the structure of the child class... – marvinIsSacul Nov 15 '18 at 08:40
  • 1
    The error I get is : Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) @Yksisarvinen – Alexandra Nov 15 '18 at 08:45
  • @marvinIsSacul I added the header and .cpp file of the child class in my edit. – Alexandra Nov 15 '18 at 08:45
  • Where are you allocating memory for the `list` array? Or for `sortIndicesGainLoss` for that matter – UnholySheep Nov 15 '18 at 08:47
  • Where I use the "new" keyword? I haven't used the new keyword at all. Maybe that's the reason why. I just don't know how to assign those new dynamic objects to pre-existing objects? – Alexandra Nov 15 '18 at 08:49
  • I thought you could create a pointer and just assign its indexes to objects as you pleased, I didn't know you had to use "new?" Is that what you mean by allocating memory for it? – Alexandra Nov 15 '18 at 08:50
  • 1
    You have uninitialized pointers, they don't point to valid memory - dereferencing them like you do invokes *undefined behavior*. That has nothing to do with templates or inheritance. Also you should prefer `std::vector` over pointers for this – UnholySheep Nov 15 '18 at 08:51
  • 1
    *"I thought you could create a pointer and just assign its indexes to objects as you pleased"* - Where did you learn that? It's completely wrong and any decent course or textbook should be explaining it – UnholySheep Nov 15 '18 at 08:52
  • We have not learned about vectors yet in school, maybe I should take up and learn that. I'm still very new to programming, but I guess I should be practicing more. – Alexandra Nov 15 '18 at 08:55
  • I thought I initialize list in my constructor? In my listType constructor, that is – Alexandra Nov 15 '18 at 08:58
  • Thank you, that's the reason I keep getting errors. – Alexandra Nov 15 '18 at 09:09
  • Now I'm getting an error around the point where I do: sortIndicesGainLoss = list; The error says: Thread 1: breakpoint 1.1 – Alexandra Nov 15 '18 at 09:13

2 Answers2

2

elemType *list; is not initialized. I really think that's the problem right there. try initializing it in the constructor to something like

list = new elemType [5]; since you'll be using 5 elements.

listType(const elemType &, const elemType &, const elemType &, 
const elemType &, const elemType &){

    this->list = new elemType [5];

    list[0] = a;
    list[1] = b;
    list[2] = c;
    list[3] = d;
    list[4] = e;

}
marvinIsSacul
  • 803
  • 4
  • 23
  • Now I'm getting an error around the point where I do: sortIndicesGainLoss = list; – Alexandra Nov 15 '18 at 09:12
  • try not using `sortIndicesGainLoss`. try removing `sortIndicesGainLoss = list;` and use `list` directly. – marvinIsSacul Nov 15 '18 at 09:18
  • so replace every instance of `sortIndicesGainLoss` with `list` – marvinIsSacul Nov 15 '18 at 09:19
  • @JeJo perhaps Alexandra wants to learn about pointers, and manual memory management before going on to use already implemented libraries. We should not judge people on their methodology of programming. – marvinIsSacul Nov 15 '18 at 09:33
  • I appreciate the help @JeJo. In all honesty, that article you linked to confuses me (Rule of three/five.) o.O. I will learn how to use vectors when I have the time, as a busy college student and with other things such as bible studies, I barely have enough time! Thank you marvinIsSacul also for all your help. I am now having a problem with my sortList() method for some reason. – Alexandra Nov 15 '18 at 09:36
2

The problem is, in the constructor of listType you are not allocating memory for the array list. If your class has a member of type * elemType, this would be a pointer to a elemType, but it does not mean it points to allocated memory. A solution to your problem is to write the constructor of listType as follows:

listType(const elemType &, const elemType &, const elemType &, 
const elemType &, const elemType &) : list(new elemType[5]) {

list[0] = a;
list[1] = b;
list[2] = c;
list[3] = d;
list[4] = e;

}

But then do not forget to deallocate list when your object gets destructed. You need a distructor inside the definition of the class list as:

virtual ~listType { delete[] list; }

The destructor should be virtual, see the discussion here

That said, rather than using C-style arrays, if the size of the array list is known at compile time, I would rather suggest to use the C++11 arrays. So, in the declaration of the class listType your protected member list should be declared as

std::array<elemType, 5> list;

Then you do not need anymore to allocate and deallocate "manually" the array list. Also, you need to #include <array>

As for the second error when sortIndicesGainLoss = list;: you do not need the member stockType *sortIndicesGainLoss. In fact, by calling the constructor of the base class listType, you have already initialized the array list of elemType, which, being protected, is accessible to stockListType. So to solve the problem:

  • Remove stockType *sortIndicesGainLoss from the declaration of stockListType

  • In the cpp file remove sortIndicesGainLoss = list;, and everywhere use the inherited member list instead of sortIndicesGainLoss

francesco
  • 4,122
  • 7
  • 15
  • 31
  • Thank you so much. This really helps. So when I use a C++11 array, I do not need to use delete [] anymore? I will have to use that from now on. – Alexandra Nov 15 '18 at 09:30
  • Also, now I am getting an error under my sortList() method. Do you happen to know why? – Alexandra Nov 15 '18 at 09:31
  • @Alexandra: If you declare ```list``` as a C++11 you do not need to use ```delete[]```. You should think it like a normal variable, which gets automatically deleted when it exits the scope. For the error in ```sortList()``` please check first my updated answer. – francesco Nov 15 '18 at 09:37
  • @francesco I seriousy don't understand why you and others are throwing the kid with the std library. Because I think the kid wants to learn the language first (hence he creates his own algorithms), not the libraries. He'll get to learn them as time goes on. – marvinIsSacul Nov 15 '18 at 09:42
  • @marvinIsSacul I think I have proposed *both* to "manually" use arrays and a self-defined swap, or to use the std library.... – francesco Nov 15 '18 at 09:47
  • Alright, it's alright everyone, both are helpful jeesh lol. And changing the swap to listType variables and changing temp as a variable of listType caused an error. 0.0 – Alexandra Nov 15 '18 at 09:58
  • I have another class called stockType which I didn't post here.... maybe that's confusing you? – Alexandra Nov 15 '18 at 10:02
  • @Alexandra what error do you get now? can you post the modified swap you are trying to use? – francesco Nov 15 '18 at 10:15
  • Since in my for loop list[j] and list[j+1] are referring to stockType objects since my list array is a pointer to an array of stockType objects it gives me an error: Non-const lvalue reference to type 'listType' cannot bind to a value of unrelated type 'stockType' – Alexandra Nov 15 '18 at 10:24
  • Where the for loop starts at for(int i =0; i<5; i++) it gives me a green error message saying Thread 1: breakpoint 1.1 – Alexandra Nov 15 '18 at 10:26
  • @Alexandra: sorry, your ```swap``` should be actually OK. – francesco Nov 15 '18 at 10:39
  • Thank you @francesco! I found out my problem. I accidentally put in a breakpoint in my xcode OTL. It was causing my code to stop at that point and I thought it was an error message. Lol. Thank you. – Alexandra Nov 16 '18 at 05:52