Declare size of a vector inside class - c++

I am trying to declare the size of a vector inside a class. I want the vector size equal to another attribute of this same class. Vector "table" is inside the class Hashtable. "bucket_count" is the intended size for the vector "table". the error given is "member is not a type name". Please let me know what another way I can declare the size of a vector inside the class. If not, then what is the way out? Thanks.
Please refer to the code below.
class HashTable {
public:
int bucket_count;
vector<list<string>> table(bucket_count);
//bool isEmpty(list<string> &cell) const;
int hashFunction(const string& s);
void insertItem(string value);
void removeItem(string value);
bool searchTable(string s);
void printTable();
void processQueries();
void processQuery(const Query& query);
};

I tried making a constructor which worked for me, but I am not sure why it worked.
Here is my code:
HashTable::HashTable(int bc)
: bucket_count(bc)
, table(bucket_count)
{}
In this, the bucket_count is initialized to bc in this constructor which is agreeable. But by that logic table should be initialized to bc. But that is not what happened. Instead the size of table vector got initialized (which is what I wanted).
If anyone could explain, why the constructor initialization worked this way it would be of great help.

The easiest solution would be
vector<list<string>> table{(size_t)bucket_count};

This depends largely on how, where and when you set the actual value of bucket_count. For example, you could set the size of the table vector in the initializer list of your class constructor. The following code lets you do this by setting the size in the constructor call, either by passing a size explicitly when you construct a class object, or by using a default value (42 in the code I've shown):
class HashTable {
public:
int bucket_count;
vector<list<string>> table;
HashTable(int bc = 42) : bucket_count(bc), table(bucket_count) { }
//...
Alternatively, if bucket_size is to remain constant and universal, you could make it a static constexpr member:
class HashTable {
public:
static constexpr auto bucket_count = 42;
vector<list<string>> table;
HashTable() : table(bucket_count) { }
//...

Related

Initialize a dynamic vector list

I am trying to initialize my MedList but it's not working. Here's what I'm talking about:
repository.h
#include "../domain/farmacy.h"
#include "../utils/DynamicVector.h"
class Repository{
private:
DynamicVector<Medicine>* MedList; //I made it pointer so it can be dynamic
public:
Repository(); //constructor
repository.cpp
#include "../domain/farmacy.h"
#include "repository.h"
#include "../utils/DynamicVector.h"
#include <stdlib.h>
Repository::Repository(){
this->MedList=new DynamicVector<Medicine>::DynamicVector(); //error
}
DynamicVector.h
template <typename Element> //this is the Dynamic Vector constructor
DynamicVector<Element>::DynamicVector()
{
this->cap=10;
this->len=0;
this->elems=new Element[this->cap];
}
the error above is:
Multiple markers at this line
- no match for 'operator=' in '((Repository*)this)->Repository::MedList = (int*)operator
new(4u)'
- expected type-specifier
- candidate is:
- expected ';'
this is the medicine class
class Medicine{
private:
int ID;
std::string nume;
double concentratie;
int cantitate;
The Dynamic Vector class:
template <typename Element>
class DynamicVector{
private:
Element* elems;
int cap;
int len;
void resize();
void CopyToThis(const DynamicVector& v);
public:
DynamicVector(); //constructor implicit
DynamicVector(const DynamicVector& ); //constructor de copiere
DynamicVector& operator=(const DynamicVector& );
~DynamicVector();
void addElement(Element elem);
Element delElementAtPosition(int pos);
Element getElementAtPosition(int pos);
int getLen();
};
What am I doing wrong? I tried a lot of variants but nothing seems to work. Could you help me?
I think you're confusing c++ syntax for creating object with some other language, e.g. Java or C#.
In c++, a constructor is called simply by declaring the variable:
DynamicVector<Element> medList; // Calls DynamicVector<Element>::DynamicVector()
The new operator in C#, is to dynamically allocate space for a variable, and returns a pointer to the allocated space. To use it here, you'd have to declare Repository::MedList as a pointer type, and initialize it like so:
DynamicVector<Medicine>* MedList; // in repository.h
this->MedList = new DynamicVector<Medicine>(); // in repository.cpp
However, as Andy Prowl pointed out, it is much better to just let the compiler do the memory management for you. To do so, you should completely remove the erroneous line in repository.cpp. Why? Well, when the repository is constructed, the compiler also tries to construct all member objects using their default constructors. This is exactly what you want, so there is no reason to try to alter the compiler's behavior.
Constructor should be:
Repository::Repository(){
this->MedList=new DynamicVector<Medicine>;
}
DynamicVector() calls the constructor for DynamicVector.
DynamicVector::DynamicVector() is a pointer to the address of the constructor function
The chances are your C++ version doesn't allow empty () for constructors.
this->MedList=new DynamicVector<Medicine>::DynamicVector(); //error
should be
this->MedList=new DynamicVector<Medicine>::DynamicVector;
or (The usual way of writing it)
this->MedList=new DynamicVector<Medicine>;
See here for more info.
EDIT. Make sure you have declared the dynamicVector constructor in the class.
Default constructor with empty brackets
Do the parentheses after the type name make a difference with new?

changing private variable in the same class?

I am working on an c++ hw assignment so I will try not to post too much code as possible, what we are working on is as following: we have a class that include a public swap function (along with insert and delete functions and such) and a private struct array to store the data.
something like:
Class set
public:
set(int dimension);
insert();
delete();
swap(set& swapset);
private:
struct *set;
now in the main we have set s1 and set s2, when I run swap like so: s1.swap(s2); s1 and s2 will swap the whole array and we need to keep the dimension of each array (so if s1 was set=new set[3] and s2 is set=new set[5]) after swap s1 is [5] and s2 is [3]
I was able to use insert and delete functions to swap the arrays when it was fixed dimension but I can't figure out how to change the dimension of the arrays during the swap function since the *set is private right?
thanks in advance for all the help!
edit: I added some parts of the code since I can't explain it correctly:
set::set()
:counter(0),m_size(0),flag(0)
{
m_set=new set[DEFAULT_MAX_ITEMS];
swapper=new set[DEFAULT_MAX_ITEMS];
maxsize=DEFAULT_MAX_ITEMS;
}
set::set(int x)
:counter(0),m_size(0),flag(0)
{
m_set=new set[x];
swapper=new set[x];
maxsize=x;
}
void set::swap(set& other)
{
// Exchange the contents of this set with the other one.
int tempmaxsize=maxsize;
int tempcounter=counter;
int tempmsize=m_size;
swapper=m_set;
m_set=other.m_set;
other.m_set=swapper;
m_size=other.m_size;
counter=other.counter;
maxsize=other.maxsize;
other.counter=tempcounter;
other.m_size=tempmsize;
other.maxsize=tempmaxsize;
}
private:
struct set
{
ItemType entry;
int count;
};
int maxsize;
set* m_set;
int m_size;
int counter;
int flag;
set* swapper;
error code is this:
debug assertion failed!
expression:_block_type_is_valid(phead->nblockuse)
Actually changing array sizes should be part of the swap function and so should be done in a class method. As it is a class method, it has access to private members.

Values from vector differ from the original value

I am confused with C++ vector and ask for help.
I declare a class CBoundaryPoint:
class CBoundaryPoint:
{
public:
double m_param;
int m_index;
}
And then I define a vector:
vector<CBoundaryPoint> vBoundPoints;
CBoundaryPoint bp;
double param;
// other codes
bp.m_param = param;
vBoundPoints.push_back( bp );
It surprises me that for every element in vBoundPoints, the value of m_param is totally different from the given value param. I just don't know why.
For Example:
param = 0.3356;
bp.m_param = param; // so bp.param equals to 0.3356;
vBoundPoints.push_back( bp ); // while (*(vBoundPoints.end()-1)).m_param = -6.22774385622041925e+066; same case to other elements
So what happened and why? I'm using VS2010.
You probably get garbage when you resize the vector or create a vector of a certain size using the size_type constructor. You get default-constructed objects in your vector, and these contain primmitive types. Since you have no user defined default constructor, the values are essentially random, or "garbage".
You can fix this by adding a default constructor to your class:
class CBoundaryPoint:
{
public:
CBoundaryPoint : m_param(), m_index() {} // initializes members to 0. and 0
double m_param;
int m_index;
}

Initialize size of vector<list<DATA> > and accesses

Hey I'm a little confusd about how the constructor initializes the size of the vector >.
This is my hpp
#include <vector>
#include <list>
#include <ostream>
using namespace std ;
typedef struct { double successful[2] , unsuccessful[2] ; } Perform ;
template <class DATA>
class Table {
private :
vector<list<DATA> > theList;
typename list<DATA>::iterator itr;
unsigned listSize;
unsigned actualSize;
unsigned probe;
...
and in my cpp
template <class DATA> Table<DATA>::Table(unsigned int size)
{
listSize = size;
actualSize = 0;
probe = 0;
theList(size); //Not sure how to make the vector of size "size"
}
and if I wanted to clear the lists in each vector location could I do a for loop and have the code be
theList[i].clear();
or would i have to do something different?
One last question is for inserting something into each of the lists in side the vectors, can I do
theList[i].push_back(data);
if not how do I do it?
Thanks for the help.
Congratulations, you have discovered the difference between initialization and assignment.
Assignment occurs when you try to set an existing object to a new value; initialization is when an object is created and its constructor is called.
What you're doing in your constructor (which, for some reason, isn't shown in your header, making your code more confusing than it has to be) is assignment. By the time the constructor body executes, all members have been initialized.
To initialize a member, use the initializer list syntax:
template <class DATA> Table<DATA>::Table(unsigned int size)
: listSize(size), actualSize(0), probe(0), theList(size)
{
}
This will call the constructor for each of the specified elements, with the specified arguments.
To set initial size you can use initialer list,
template <class DATA> Table<DATA>::Table(unsigned int size)
: theList(size)
{
...
or by calling resize method inside:
theList.resize(size);
For your first question, the code is right. This will create a vector with size elements, these elements will be default-constructed, which in ths case means they're empty lists. BUT you should place this initialization in the initialization list as follows (you should also do this for the other members btw).
template <class DATA> Table<DATA>::Table(unsigned int size) : theList(size)
{
...
}
This will prohibit the constructor from first calling the default constructor of your theList object (so it is a valid object).
The answer to your other questions is yes, but if you use C++11 you can probably save some tedious for-loops by using for_each and lambdas, for example like this:
std::for_each(theList.begin(),theList.end(),[&data](std::list& l) { l.push_back(data)});

Intitialzing an array in a C++ class and modifiable lvalue problem

I have a basic C++ class .The header looks like this:
#pragma once
class DataContainer
{
public:
DataContainer(void);
~DataContainer(void);
int* getAgeGroup(void);
int _ageGroupArray[5];
private:
int _ageIndex;
};
Now inside the cpp file of the class I want to intialize the _ageGroupArray[5] with default values inside the class contructor like this:
#include "DataContainer.h"
DataContainer::DataContainer(void)
{
_ageGroupArray={20,32,56,43,72};
_ageIndex=10;
}
int* DataContainer::getAgeGroup(void){
return _ageGroupArray;
}
DataContainer::~DataContainer(void)
{
}
Doing it I am getting "Expression must be a modifiable lvalue" on _ageGroupArray line.So is it entirely impossible to initialize an array object in the constructor? The only solution I found was to define the array outside scope identifiers .Any clarification on this will be greatly appreciated.
In the current standard, as you have already noticed, you cannot initialize a member array in the constructor with the initializer list syntax. There are some workarounds, but none of them is really pretty:
// define as a (private) static const in the class
const int DataContainer::_age_array_size = 5;
DataContainer::DataContainer() : _ageIndex(10) {
int tmp[_age_array_size] = {20,32,56,43,72};
std::copy( tmp, tmp+_age_array_size, _ageGroupArray );
}
If the values in the array are always the same (for all object in the class) then you can create a single static copy of it:
class DataContainer {
static const int _ageGroupArraySize = 5;
static const int _ageGroupArray[ _ageGroupArraySize ];
// ...
};
// Inside the cpp file:
const int DataContainer::_ageGroupArray[_ageGroupArraySize] = {20,32,56,43,72};
You can Initialize a array when you Create/Declare it, not after that.
You can do it this way in constructor :
_ageGroupArray[0]=20;
_ageGroupArray[1]=32;
_ageGroupArray[2]=56;
_ageGroupArray[3]=43;
_ageGroupArray[4]=72;
It is important to know that this is Assignment & not Initialization.
try this:
int ageDefault[]={20,32,56,43,72};
memcpy(_ageGroupArray, ageDefault, sizeof(ageDefault));