Printing std::strings produces no output - c++

I was building a small template stack class for a side project and it appeared to be working correctly. However, when I tried it with strings it doesn't appear to work. I have no compilation errors or warnings. I simply get no output. I'm a little rusty in C++ but I wasn't expecting to get blocked by a problem that seems this simple.
My main function (for testing):
#include <iostream>
#include <fstream>
#include <string>
#include "myStack.h"
int main()
{
bool repeat = true;
int option = -1;
std::cout << "Option (1 - String | 2 - Integer) : ";
std::cin >> option;
std::cout << "\n";
switch (option)
{
case 1:
{
myStack<std::string> stringStack;
stringStack.push("!");
stringStack.push("there");
stringStack.push("Hello");
stringStack.show();
break;
}
case 2:
{
myStack<int> intStack;
intStack.push(3);
intStack.push(2);
intStack.push(1);
intStack.show();
break;
}
default:
break;
}
std::cout << "\n";
return 0;
}
Relevant parts of my stack class:
#pragma once
template <typename T>
class myStack
{
private:
T *elements;
size_t capacity;
public:
myStack();
T top();
size_t size();
void push(T pushed);
void pop();
bool isEmpty();
void show(std::ostream &out = std::cout);
};
template <typename T>
myStack<T>::myStack()
{
this->elements = NULL;
this->capacity = 0;
}
template <typename T>
void myStack<T>::push(T pushed)
{
this->elements = (T *)realloc(this->elements, (this->capacity + 1) * sizeof(T));
this->elements[this->capacity] = pushed;
this->capacity++;
}
template<typename T>
void myStack<T>::show(std::ostream &out)
{
for (int i = this->capacity - 1; i >= 0; i--)
{
out << this->elements[i] << std::endl;
}
}

Use of
this->elements = (T *)realloc(this->elements, (this->capacity + 1) * sizeof(T));
this->elements[this->capacity] = pushed;
to manage an array of std::strings is not right. Use of realloc to allocate memory is ok. However, it does not initialize the object properly. The second line is cause for undefined behavior since the object was not initialized properly.
If you are allowed to use std::vector, use it.
template <typename T>
class myStack
{
private:
std::vector<T> elements;
...
};
Then, use of capacity can be replaced by elements.size().
push can be simplified to:
template <typename T>
void myStack<T>::push(T pushed)
{
this->elements.push_back(pushed);
}
You'll have to update show() accordingly too.

Related

BST inorder method referencing vector showing error: declaration is incompatible

I am a beginner at c++ and I am coding a program that stores data into a BST template class the being another class called log_t that stores the variables, I am trying to use the inorder method from the BST class to reference a vector from main, to input the values into and be able to use it in the main class
my main class
int main(int argc, char* argv[])
{
BST<log_t> l;
string infilename = "";
string filePath = "data\\";
string files[1] = {
filePath + "MetData-31-3a.csv"
//filePath + "Jan20071toDec31abcdefghijklmnopq",
//filePath + "Jan20081toDec31abcdefghijklmnopq",
//filePath + "MetData_Jan01-2010-Jan01-2011-ALL"
};
/// checks if file can open
for (int i = 0; i < 1; i++) {
infilename = files[i];
ifstream infile(infilename);
if (!infile.is_open())
{
cout << "unable to read file" << files[i] << endl;
}
else
{
cout << "reading file" << files[i] << endl;
}
/* parse sensor data csv file */
string tmp;
getline(infile, tmp); // skip the first line
while (getline(infile, tmp))
{
// if successfully parsed then append into vector
log_t logline;
if (ParseLog(tmp, logline))
l.insert(logline);
}
}
cout << " end with reading file" << endl;
/* aggregate/filter logs */
Vector<log_t> vec;
l.inorder(vec);
/* prompt menu */
// this array stores all the menu option callback functions
void(*funs[])(const Vector<log_t> & vec) = { NULL, &option1, &option2, &option3, &option4, &option5,&option6 };
// keep printing menu in loop
while (true)
{
// prompt menu and ask user to select option
int choice = PromptMenu();
// check validity of choice
if (choice < 1 || choice > 6)
{
cout << "invalid choice" << endl;
}
else
{
cout << endl;
// call menu option handler
(funs[choice])(vec);
}
}
system("pause");
return -1;
}
my BST class
#include <string>
#include <iostream>
#include <stream>
#include <iomanip>
#include <stream>
#include "date.h"
#include "times.h"
#include "log_t.h"
#include "Vector.h"
using namespace std;
template <class T>
class BST {
private:
struct Node {
T num;
Node* left;
Node* right;
};
Node* root = NULL;
Node* insert(Node* node, T x);
Node* newnode(T num);
void removeprivate(T num, Node* parent);
T findsmallestprivate(Node* ptr);
void inorderprivate(Node* ptr, void (BST<T>::* FT)(T&), Vector<log_t>const& log);
void postorderprivate(Node* ptr, void (BST<T>::* FT)(T&));
void preorderprivate(Node* ptr, void (BST<T>::* FT)(T&));
//void inorderprivate(Node* ptr);
//void postorderprivate(Node* ptr);
//void preorderprivate(Node* ptr);
void removematch(Node* parent, Node* match, bool left);
public:
void insert(T num);
void remove(T num);
void removerootmatch();
T findsmallest();
void inorder(Vector<log_t>const& log);
void postorder();
void preorder();
void print(T& p) { cout << p << " "; };
};
template <class T>
void BST<T>::inorder(Vector<log_t>const& log) {
inorderprivate(root,print,log);
}
template <class T>
void BST<T>::inorderprivate(Node* ptr, void (BST<T>::* FT)(T&), Vector<log_t>const&
log) {
if (root != NULL)
{
if (ptr->left != NULL)
{
inorderprivate(ptr->left, FT);
}
(this->*FT)(log);
log.Append( ptr->num);
if (ptr->right != NULL)
{
inorderprivate(ptr->right, FT);
}
}
else
{
cout << "tree is empty";
}
}
my log_t class the T type
#pragma once
#ifndef LOG_T_H
#define LOG_T_H
#include <iostream>
#include <stream>
#include <string>
#include <algorithm>
#include <iomanip>
#include <stream>
#include "date.h"
#include "times.h"
#include "BST.h"
class log_t
{
public:
log_t();
log_t(log_t& log);
float gettemp();
float getwind();
float getsolar();
void setwind(float wind);
void setsolar(float rad);
void settemp(float temp);
Date date;
Times time;
private:
float wind_speed;
float solar_radiation;
float air_temperature;
};
log_t::log_t()
{
wind_speed = 0;
solar_radiation = 0;
air_temperature = 0;
}
log_t::log_t(log_t& log) {
wind_speed = log.wind_speed;
solar_radiation = log.solar_radiation;
air_temperature = log.air_temperature;
date.SetDate(log.date.GetDay(), log.date.GetMonth(), log.date.GetYear());
time.SetHour(log.time.GetHour());
time.SetMinute(log.time.GetMinute());
}
float log_t:: gettemp()
{
return air_temperature;
}
float log_t::getwind() {
return wind_speed;
}
float log_t::getsolar() {
return solar_radiation;
}
void log_t::setwind(float wind)
{
wind_speed = wind;
}
void log_t::setsolar(float rad)
{
solar_radiation = rad;
}
void log_t::settemp(float temp)
{
air_temperature = temp;
}
#endif // LOG_T_H
my vector class
#pragma once
#ifndef VECTOR_H
#define VECTOR_H
#include <iostream>
#include <stream>
#include <string>
template <class T>
class Vector
{
public:
Vector();
Vector(int capacity);
Vector(const Vector& vec);
Vector& operator=(const Vector& vec);
~Vector();
int GetSize() const;
void Expand();
T& GetLast();
void Append(const T& val);
T& operator[](int idx);
const T& operator[](int idx) const;
private:
T* elems;
int capacity;/** < int capacity, stores the size of the array */
int count;
void CopyFrom(const Vector& vec);
};
template <class T>
inline Vector<T>::Vector() : elems(nullptr), capacity(0), count(0)
{
}
template <class T>
inline Vector<T>::Vector(int capacity)
: elems(new T[capacity]()), capacity(capacity), count(0)
{
}
template <class T>
inline Vector<T>::Vector(const Vector& vec)
{
CopyFrom(vec);
}
template <class T>
inline Vector<T>& Vector<T>::operator=(const Vector& vec)
{
if (elems)
delete[] elems;
CopyFrom(vec);
return *this;
}
template <class T>
inline Vector<T>::~Vector()
{
if (elems)
delete[] elems;
}
template <class T>
inline int Vector<T>::GetSize() const
{
return count;
}
template <class T>
inline void Vector<T>::Expand()
{
++count;
if (count > capacity)
if (capacity)
capacity *= 2;
else
capacity = 4;
T* tmp = new T[capacity]();
for (int i = 0; i < count - 1; ++i)
tmp[i] = elems[I];
if (elems)
delete[] elems;
elems = tmp;
}
template <class T>
inline T& Vector<T>::GetLast()
{
return elems[count - 1];
}
template <class T>
inline void Vector<T>::Append(const T& oval)
{
Expand();
GetLast() = val;
}
template <class T>
inline T& Vector<T>::operator[](int idx)
{
return elems[idx];
}
template <class T>
inline const T& Vector<T>::operator[](int idx) const
{
return elems[idx];
}
template <class T>
inline void Vector<T>::CopyFrom(const Vector& vec)
{
elems = new T[vec.capacity]();
capacity = vec.capacity;
count = vec.count;
for (int i = 0; i < count; ++i)
elems[i] = vec.elems[i];
}
#endif //VECTOR_H
the errors that keep showing up are
Severity Code Description Project File Line Suppression State
Error (active) E0147 declaration is incompatible with "void BST::inorder(const Vector<> &log)" (declared at line 241 of "C:\Users\Frances\Documents\A2\A2\BST.h") A2 C:\Users\Frances\Documents\A2\A2\BST.h 241
Severity Code Description Project File Line Suppression State
Error C2065 'log_t': undeclared identifier A2 C:\Users\Frances\Documents\A2\A2\BST.h 33
Severity Code Description Project File Line Suppression State
Error C2923 'Vector': 'log_t' is not a valid template type argument for parameter 'T' A2 C:\Users\Frances\Documents\A2\A2\BST.h 33
could someone help me figure out what it is that's causing this or what I am doing wrong, I have been trying to find an answer for hours and haven't been successful thank you

Debug Assertion Failed! C++ VS2012 - Template Class

I'm doing an assignment and I've put together a template class for a Vector, and now have inherited it (per the assignment) to make it a sort-able. At the very end of the void SearchableVector<T>::add(T itemToAdd) method it throws a Debug Assertion Failed! error. The full text of the error is as follows:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!
Program: ...tudio 2012\Projects\COSC 1437\Program 10\Debug\Program 10.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------
I've looked around and I realize this is a pretty common error usually related to memory management. Often calling delete on inappropriate things. I must be doing something similar because I'm getting the error, but I cannot find what I'm doing wrong. If you could help me out and/or point me in the right direction that would be much appreciated.
Main.cpp
#include "SimpleVector.h"
#include "SearchableVector.h"
#include <stdlib.h>
#include <time.h>
void main()
{
srand (time(NULL));
SearchableVector<int> v(0);
for (int i = 0; i < 20; i++)
{
v.add(rand() % 20);
}
v.print();
}
SimpleVector.h
#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <stdexcept>
#include <iomanip>
using namespace std;
template<class T>
class SimpleVector {
public:
//Constructors
SimpleVector(); //default constructor, size 0
SimpleVector(int); //parameterized constructor with default size
SimpleVector(const SimpleVector& a); //copy constructor
~SimpleVector(); //destructor
T& operator[](int) const;
SimpleVector<T>& operator=(SimpleVector<T>);
const bool operator==(SimpleVector&) const;
void push_back(T);
T& pop_back();
T& getElement(int);
int getSize() const;
void print() const;
protected:
int size;
T* internalArray;
void SimpleVector<T>::swap(SimpleVector&);
};
template<class T>
SimpleVector<T>::SimpleVector()
{
size = 0;
internalArray = nullptr;
}
template<class T>
SimpleVector<T>::SimpleVector(int sizeOfArray)
{
if (sizeOfArray < 0) throw "SimpleVector size must not be less than 0";
internalArray = new T[sizeOfArray]();
size = sizeOfArray;
}
template<class T>
SimpleVector<T>::SimpleVector(const SimpleVector& vectorToCopy):size(vectorToCopy.getSize()), internalArray( new T[vectorToCopy.getSize()] )
{
for (int i = 0; i < size; i++)
internalArray[i] = vectorToCopy.internalArray[i];
}
template<class T>
SimpleVector<T>::~SimpleVector() {
//cout << "Destructor called" << std::endl;
delete[] internalArray;
}
template<class T>
T& SimpleVector<T>::operator[](int i) const {
if (i<0 || i>=size) throw "Vector::operator[] : index is out of range";
return internalArray[i];
}
template<class T>
SimpleVector<T>& SimpleVector<T>::operator=(SimpleVector<T> rightSide) {
rightSide.swap(*this);
return *this;
}
template<class T>
const bool SimpleVector<T>::operator==(SimpleVector& right) const {
if (size() != right.size())
return false;
else {
for (int i = 0; i < size(); i++){
if (internalArray[i] != right[i])
return false;
}
}
return true;
}
template<class T>
void SimpleVector<T>::push_back(T itemToAdd) {
SimpleVector<T> temp(size + 1);
for (int i = 0; i < size; i++)
temp[i] = internalArray[i];
temp[size] = itemToAdd;
temp.swap(*this);
}
template<class T>
T& SimpleVector<T>::pop_back()
{
SimpleVector<T> temp(size - 1);
for (int i = 0; i < size; i++)
temp[i] = internalArray[i];
T pop = internalArray[size-a];
temp.swap(*this);
return pop;
}
template<class T>
T& SimpleVector<T>::getElement(int indexToGet)
{
return internalArray[indexToGet];
}
template<class T>
int SimpleVector<T>::getSize() const {
return this->size;
}
template<class T>
void SimpleVector<T>::print() const
{
for (int i = 0; i < size; i++)
{
std::cout << internalArray[i];
if (i!=(size-1))
std::cout << ",";
else
std::cout << std::endl;
if (i%10 == 0 && i!=0)
std::cout <<std::endl;
}
}
template<class T>
void SimpleVector<T>::swap(SimpleVector& other)
{
std::swap(internalArray, other.internalArray);
std::swap(size, other.size);
}
#endif
SearchableVector.h
#ifndef SEARCHABLEVECTOR_H
#define SEARCHABLEVECTOR_H
#include "SimpleVector.h"
template<class T>
class SearchableVector : protected SimpleVector<T>
{
public:
SearchableVector(int);
SearchableVector(const SearchableVector&);
~SearchableVector();
void add(T);
T getElement(int);
int getSize() const;
void print() const;
int search(T);
};
template<class T>
SearchableVector<T>::SearchableVector(int sizeOfArray) : SimpleVector(sizeOfArray)
{
}
template<class T>
SearchableVector<T>::SearchableVector(const SearchableVector& vectorToCopy) : SimpleVector(vectorToCopy)
{
}
template<class T>
SearchableVector<T>::~SearchableVector()
{
delete[] internalArray;
}
template<class T>
void SearchableVector<T>::add(T itemToAdd)
{
bool flag = false;
SearchableVector<T> temp(size + 1);
for (int i = 0; i < size; i++)
{
if ((itemToAdd <= internalArray[i]) && (flag == false))
{
temp[i] = itemToAdd;
i++;
flag = true;
}
temp[i] = internalArray[i];
}
if (flag == false)
temp[size] = itemToAdd;
temp.swap(*this);
} // !*******************! THROWS THE ERROR RIGHT HERE !*******************!
template<class T>
T SearchableVector<T>::getElement(int elementToGet)
{
return SimpleVector::getElement(elementToGet);
}
template<class T>
int SearchableVector<T>::getSize() const
{
return SimpleVector::getSize();
}
template<class T>
void SearchableVector<T>::print() const
{
SimpleVector::print();
}
template<class T>
int SearchableVector<T>::search(T itemToSearchFor)
{
}
#endif
First of all, when using inheritance, 99% of the time you should use a virtual destructor.
That's very important.
virtual ~SimpleVector();
When deleting an object, its base class destructor is called too.
And in your case you have delete[] internalArray; in both destructors.
Just leave that delete in the base class, because that member belongs to it, and it should take care of it.
Next time you encounter something like this, put a breakpoint near all the delete calls for that object type, then you can see which ones are called and in what order.

Use of pointers in a stack class?

I'm learning C++, and we were given an exercise to make a stack class using a class template and pointers. I'm not yet fully understanding the implementation of a stack or pointers so I gave it a go and made this class:
template <class T>
class Stack_Class {
public:
T* stack;
int item_quantity;
T* First_item;
int Max_quantity;
Stack_Class(int value);
~Stack_Class();
bool Add(T value);
T Pop();
int GetMax_Quantity();
bool Full();
bool Empty();
};
template <class T>
Stack_Class<T>::Stack_Class(int value) {
if (value > 0) {
stack = new T[value];
First_item = stack;
item_quantity = 0;
Max_quantity = value;
}
}
template <class T>
Stack_Class<T>::~Stack_Class() {
if (First_item) {
delete First_item;
}
}
template<class T>
bool Stack_Class<T>::Add(T num) {
if (item_quantity <Max_quantity) {
*stack = num;
stack++;
item_quantity++;
return true;
}
else return false;
}
template<class T>
T Stack_Class<T>::Pop() {
if (!Empty()) {
item_quantity--;
return stack[item_quantity];
}
return NULL;
}
template<class T>
bool Stack_Class<T>::Empty() {
return (item_quantity == 0);
}
template <class T>
int Stack_Class<T>::GetMax_Quantity() {
return Max_quantity;
}
And the main class would be:
#include <iostream>
#include "Stack_Class.h"
void main() {
Stack_Class<int> intStack(3);
intStack.Add(1);
intStack.Add(2);
intStack.Add(3);
int count = intStack.GetMax_Quantity();
for (int i = 0; i < count; i++) {
std::cout << "Pop No: " << i << " - Elemento: " << intStack.Pop() << std::endl;
}
}
Though as a result I'm getting all random numbers instead of the ones I gave it in intStack. Add, so my question would be I'm implementing the pointer correctly here?
You need to deincrement the stack pointer before you reference it within Pop():
template<class T>
T Stack_Class<T>::Pop(){
if (!Empty()){
item_quantity--;
stack--;
return *stack;
}
return NULL;
}
Your array access stack[item_quantity] does not work because you increment stack in Add. So after construction, the memory pointed to by stack looks like this
0xff65f96f <-- *(stack + 0)
0x0eec604f <-- *(stack + 1)
0x05be0582 <-- *(stack + 2)
0x29b9186e <-- *(stack + 3)
The hexdecimal values represent random garbage coincidentely located in the memory at the time of allocation. This is because memory allocated by new is not initialized to something nice. After adding three values, it looks like this
1 <-- *(stack - 3)
2 <-- *(stack - 2)
3 <-- *(stack - 1)
0x29b9186e <-- *(stack + 0)
0xf66eff06 <-- *(stack + 1)
0x357eb508 <-- *(stack + 2)
In the first call of Pop, you access stack[2] = *(stack + 2), because item_quantity is 2 after deincrementing it. The two consecutive calls to Pop access stack[1] and stack[0]. As you can see above, you never actually reference the values you’ve put into the stack.
You are mixing up the pointer incrementing semantic in the Add method and the indexing semantic in the Pop method.
Since you need the index for the Empty method and so on, I would fix your Add method instead of the Pop as can be seen below.
Otherwise, you would end up still using the indexing in some method(s), but not in other. It would not look consistent to me.
template<class T>
bool Stack_Class<T>::Add(T num){
if (item_quantity <Max_quantity){
stack[item_quantity++] = num;
return true;
}
else return false;
}
Yet another problem in your code is this:
stack = new T[value];
but you seem to only delete the first element in the pointer. That is a guaranteed (and potentially not negligible) memory leak.
Even if you fix all that, your code would not still compile since you are trying to return void, whereas a C++ program should return int, so change this:
void main(){
...
}
to:
int main(){
...
}
... and return an integer like 0 correspondingly.
You would also need to fix this warning:
Stack_Class.h:56:13: warning: converting to non-pointer type ‘int’ from NULL [-Wconversion-null]
return NULL;
^
By for instance change NULL to 0.
Having fixed all that, the output is like this:
Pop No: 0 - Elemento: 3
Pop No: 1 - Elemento: 2
Pop No: 2 - Elemento: 1
You can also see the code running on ideone.
For your convenience, this is the whole working code after those fixes:
template <class T>
class Stack_Class{
public:
T* stack;
int item_quantity;
T* First_item;
int Max_quantity;
Stack_Class(int value);
~Stack_Class();
bool Add(T value);
T Pop();
int GetMax_Quantity();
bool Full();
bool Empty();
};
template <class T>
Stack_Class<T>::Stack_Class(int value){
if (value > 0){
stack = new T[value];
First_item = stack;
item_quantity = 0;
Max_quantity = value;
}
}
template <class T>
Stack_Class<T>::~Stack_Class(){
if (First_item){
delete First_item;
}
}
template<class T>
bool Stack_Class<T>::Add(T num){
if (item_quantity <Max_quantity){
*stack = num;
stack++;
item_quantity++;
return true;
}
else return false;
}
template<class T>
T Stack_Class<T>::Pop(){
if (!Empty()){
item_quantity--;
return stack[item_quantity];
}
return NULL;
}
template<class T>
bool Stack_Class<T>::Empty(){
return (item_quantity == 0);
}
template <class T>
int Stack_Class<T>::GetMax_Quantity(){
return Max_quantity;
}

Class Template and Reference Return Type

Long-time reader, first-time poster!
A few comments before I begin: I'm not looking for anyone to do my work for me, I just need a little guidance. Also, I've done a decent amount of googling, and I haven't been able to find any solutions yet.
I have a class assignment that involves creating a template for the following class:
class SimpleStack
{
public:
SimpleStack();
SimpleStack& push(int value);
int pop();
private:
static const int MAX_SIZE = 100;
int items[MAX_SIZE];
int top;
};
SimpleStack::SimpleStack() : top(-1)
{}
SimpleStack& SimpleStack::push(int value)
{
items[++top] = value;
return *this;
}
int SimpleStack::pop()
{
return items[top--];
}
Everything seems to work except SimpleStack& push(int value):
template <class T>
class SimpleStack
{
public:
SimpleStack();
SimpleStack& push(T value);
T pop();
private:
static const int MAX_SIZE = 100;
T items[MAX_SIZE];
int top;
};
template <class T>
SimpleStack<T>::SimpleStack() : top(-1)
{}
template <class T>
SimpleStack& SimpleStack<T>::push(T value)
{
items[++top] = value;
return *this;
}
template <class T>
T SimpleStack<T>::pop()
{
return items[top--];
}
I keep getting the following errors on the definition of SimpleStack& push(int value): "use of class template requires template argument list," and "unable to match function definition to an existing declaration."
Here is main if it helps:
#include <iostream>
#include <iomanip>
#include <string>
#include "SimpleStack.h"
using namespace std;
int main()
{
const int NUM_STACK_VALUES = 5;
SimpleStack<int> intStack;
SimpleStack<string> strStack;
SimpleStack<char> charStack;
// Store different data values
for (int i = 0; i < NUM_STACK_VALUES; ++i)
{
intStack.push(i);
charStack.push((char)(i + 65));
}
strStack.push("a").push("b").push("c").push("d").push("e");
// Display all values
for (int i = 0; i < NUM_STACK_VALUES; i++)
cout << setw(3) << intStack.pop();
cout << endl;
for (int i = 0; i < NUM_STACK_VALUES; i++)
cout << setw(3) << charStack.pop();
cout << endl;
for (int i = 0; i < NUM_STACK_VALUES; i++)
cout << setw(3) << strStack.pop();
cout << endl;
return 0;
}
Sorry for the excessive code pasting!
Make it
template <class T>
SimpleStack<T>& SimpleStack<T>::push(T value) {...}

Unexplainable call to class constructor generates "matching function error"

When I call merge_sort I get a string of errors as such the most readable is:
no matching function call to dynamic_array<int>::dynamic_array()
Does having a base class instantiate a sub class cause that sub-class to re-instantiate the calling base class?
This was my first guess.
// Calling main function
#include "c_dynamic_array.cpp"
int main()
{
dynamic_array<int> d1(20);
d1.order();cout << d1 << endl;
d1.rorder();cout << d1 << endl;
d1.randorder();cout << d1 << endl;
d1.merge_sort();cout << d1 << endl; // This line starts a string of errors
}
// Dynamic Array Class and Merge Inner (merge sort) Class
#include "c_include.cpp"
/*
Dynamic Array
*/
using namespace std;
template <typename> class merge_inner;
template <class T> class dynamic_array
{
protected:
T* array;
public:
int size;
void rorder();
void order();
void randorder();
void print_operator(ostream&)const;
dynamic_array(int sizein)
{
size=sizein;
array=new T[size]();
}
void merge_sort()
{
merge_inner<T> M1;
}
};
template <class T> void dynamic_array<T>::print_operator(ostream &os=cout)const
{
for (int i = 0; i < size; i++) os << array[i] << endl;
}
template <class T> void dynamic_array<T>::randorder()
{
srand(time(NULL));
int *ap;
for(ap=array;ap!=array+size;++ap){*ap=rand()%size;}
}
template <class T> void dynamic_array<T>::order()
{
int *ap,i=0;
for(ap=array;ap!=array+size;++ap)
{
*ap=i;
++i;
}
}
template <class T> void dynamic_array<T>::rorder()
{
int *ap,i=size-1;
for(ap=array;ap!=array+size;++ap)
{
*ap=i;
--i;
}
}
template<class T> ostream& operator<<(ostream& stream, dynamic_array<T> const& data)
{
data.print_operator(stream);
return stream;
}
/*
Merge Sort
*/
template <class T> class merge_inner : public dynamic_array <T>
{
using dynamic_array<T>::array;
private:
const static int size;
T *scratch;
void flip_if_unordered(int &x, int &y)
{
if(array[x]>array[y])
{
int tmp=array[x];
array[x]=array[y];
array[y]=tmp;
}
}
void merge_algo(int &left, int &right_begin, int &right)
{
int iter,iter_left=left,iter_right=right_begin;
for(iter=left;iter<=right;++iter)
{
if( (iter_right>right) || ((iter_left < right_begin) && (array[iter_left]<=array[iter_right])))
{
scratch[iter]=array[iter_left];
++iter_left;
}
else
{
scratch[iter]=array[iter_right];
++iter_right;
}
}
for(iter=left;iter<=right;++iter){array[iter]=scratch[iter];}
}
void merge_recurse(int left,int right)
{
int left_end=(left+((right-left)/2));
int right_begin=left_end+1;
if(((left+1)==right)){flip_if_unordered(left,right);return;}
else if ((left==right)){return;}
else
{
merge_recurse(left,left_end);
merge_recurse(right_begin,right);
merge_algo(left,right_begin,right);
}
}
public:
merge_inner()
{
scratch = new T[size]();
if(scratch != NULL){merge_recurse(0, size);}
}
};
/*Quick Sort
void quick_sort()
{
quick_recurse(0,size);
}
void quick_recurse(int left, int right)
{
int l = left, r = right, tmp;
int pivot = array[(left + right) / 2];
while (l <= r)
{
while (array[l] < pivot)l++;
while (array[r] > pivot)r--;
if (l <= r)
{
tmp = array[l];
array[l] = array[r];
array[r] = tmp;
l++;
r--;
}
}
if (left < r)quick_recurse(left, r);
if (l < right)quick_recurse(l, right);
}
*/
dynamic_array seems to be missing a default constructor, and since it has a custom constructor the compiler will not provide one. Add this to your class:
dynamic_array()
{
size = 0;
array = new T[0](); // or NULL, but note that new T[0] will be != NULL
}
Alternatively, provide a default sizein for your existing constructor so that it can be used as a default constructor as well:
dynamic_array(int sizein = 0)
Since your base class dynamic_array<T> doesn't have a default constructor, every derived class constructor must call some base constructor one way or another. Put the base initialization in the constructor initializer list. For example:
template <typename T>
class merge_inner : public dynamic_array<T>
{
public:
merge_inner() : dynamic_array<T>(0) { }
// ...
};