I have written some class that moves heap allocated stuff to stack (hopefully :) ). This calss is singleton because only this class should be responsible for holding and managing part of stack. My question is: Is my code correct? Code is correct in the sense of programming (no compile errors, no memory errors and leaks (checked by valgrind)). But does the code really moves heap to stack? Here's the code:
stack.hpp:
class CStack{
public:
void* getAlloc(long);
static CStack* Instance();
private:
static bool _data[5*sizeof(double)];
static CStack* m_pInstance;
CStack(){};
CStack(const CStack&);
CStack& operator=(const CStack&);
};
stack.cpp:
#include <iostream>
#include "stack.hpp"
CStack* CStack::m_pInstance = 0;
bool CStack::_data[ 5*sizeof(double) ] = { 1 };
CStack* CStack::Instance(){
if (!m_pInstance)
m_pInstance = new CStack;
return m_pInstance;
}
void* CStack::getAlloc(long size){
std::cout << " CStack::getAlloc, " << _data << std::endl;
_pos+=size;
return &_data[0];
}
store.hpp
class CStore{
public:
CStore();
double* myAddr();
void toStack();
void out();
~CStore();
private:
double *_data;
bool _stack;
};
store.cpp:
#include <iostream>
#include <cstring>
#include "store.hpp"
#include "stack.hpp"
CStore::CStore(){
_data = new double[4];
_data[0] = 0.1;
_data[1] = 1.1;
_data[2] = 2.1;
_data[3] = 3.1;
_stack = 0;
}
double* CStore::myAddr(){ return _data; }
void CStore::toStack(){
double *tmp;
tmp = (double*)CStack::Instance() -> getAlloc(4*sizeof(double));
memcpy(tmp, _data, 4*sizeof(double));
delete [] _data;
_data = tmp;
_stack = 1;
}
CStore::~CStore(){
if (!_stack)
delete [] _data;
}
void CStore::out(){
std::cout << _data[0] << " " << _data[1] << " " << _data[2] << " " << _data[3] << std::endl;
}
main.cpp:
#include <iostream>
#include "stack.hpp"
#include "store.hpp"
using namespace std;
int main(){
CStack::Instance();
CStore a;
double stack;
cout << &stack << endl;
cout << "Adresa a " << a.myAddr() << endl;
a.out();
a.toStack();
cout << "Adresa a " << a.myAddr() << endl;
a.out();
return 0;
}
No it's utter nonsense.
First of all this code doesn't even use the stack (as long as we are speaking of the execution stack), and you clearly misunderstood the Singleton desing pattern.
You use Singleton, when you only need a single instance in your program, but you want to grant access to all functions to that single instance. Its like a global variable, but you can restrict the access.
Second, if you need to use casting in C++ like:
tmp = (double*)CStack::Instance() -> getAlloc(4*sizeof(double));
You've clearly gone wrong. Don't use void* in C++ for now. You can use it later, when you've gotten better, not for now.
The main question WHY do you wan't to move variables to the stack? if you simply want to allocate dynamicly, why still limiting it to the scope, use smart pointers, like std::auto_ptr.
if you want to create a stack, and use that to store your doubles you can write:
#include <vector>
int foo()
{
std::vector<double> stack;
// push values on the stack
stack.push_back(1.1);
stack.push_back(1.2);
stack.push_back(1.3);
// remove values from the stack
stack.pop_back();
stack.pop_back();
stack.pop_back();
}
Related
I get a LNK 2019 error in VS.
I have read a couple of similiar problems,but could not understand what i should do.As much as i understood VS can't find the template class code for some reason.I am not sure.
#include "pch.h"
#include <iostream>
#include <assert.h>
template<typename T>
struct item {
item* pointer = nullptr;
T value;
};
template <typename T>
class stack {
private:
item<T>* top;
public:
stack() { top = nullptr; };
~stack();
void push(const T& s) {
item<T>* p = top;
top = new item<T>;
assert(top != nullptr);
top->value = s;
top->pointer = p;
std::cout << "The item has been pushed." << std::endl;
}
void pop() {
T s;
if (!top) {
std::cout << "The stack is empty." << std::endl;
}
else {
s = top->value;
item<T>* p = top;
top = top->pointer;
delete p;
std::cout << "The item has been popped." << std::endl;
}
};
void check() {
if (!top) { std::cout << "The stack is empty." << std::endl; }
else { std::cout << "It has elements in it." << std::endl; }
}
};
int main()
{
stack<int> test;
return 0;
}
I want afterwards to be able to push and pop elements.So that i can continue on with my project.
You have declared a destructor for stack here:
~stack();
but you don't define it. Change the above to
~stack() { /* Clean up resources here. */ }
and it should work.
In C++, if you declare a destructor, you have to define it. Even if the destructor is pure virtual, you still have to define it or else you'll get linker error, as is the case here. If you are fine with the default destructor, but still want to declare it for some reason, for instance, to make it virtual, you can use the keyword default:
virtual ~stack() = default;
You can learn more about the default keyword here.
From what I've understood correctly:
scoped_ptr: no overhead, cannot be copied or moved.
unique_ptr: no overhead, cannot be copied, can be moved.
shared_ptr: some overhead (reference counting), can be copied.
Having said that, if there is a need for several owners, then shared_ptr should be used.
Now, in this program below which is a simple implementation of stack in C++. I don't understand which type of smart pointer should be used.
The reason I'm asking this question because both unique_ptr as well as shared_ptr cannot be copied and that is exactly what I'm doing in this implementation of simple stack. I've commented out //HERE in the program where I'm using C++ pointers and if you read the program properly you'll see how the data is getting copied in pretty much all the functions.
GameStateStack.h
#ifndef _H_GAMESTATE_
#define _H_GAMESTATE_
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <memory>
class node
{
public:
std::string gameState;
node * nextGameState; // HERE
};
class GameStateStack
{
private:
node * _topState; // HERE
void Destory();
public:
int gameStatesCount;
void PushGameState(std::string element);
void PopGameState();
std::string CurrentGameState();
GameStateStack();
~GameStateStack();
};
extern GameStateStack state;
#endif
GameStateStack.cpp
#include <iostream>
#include <stdlib.h>
#include <string>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <memory>
#include "GameStateStack.h"
#include "template.h"
GameStateStack state;
GameStateStack::GameStateStack()
{
_topState = NULL;
gameStatesCount = 0;
}
GameStateStack::~GameStateStack()
{
}
void GameStateStack::PushGameState(std::string gameStateName)
{
node *newTopState = new node; // HERE
if (_topState == NULL)
{
newTopState->gameState = gameStateName;
newTopState->nextGameState = NULL;
_topState = newTopState;
gameStatesCount++;
}
else
{
newTopState->gameState = gameStateName;
newTopState->nextGameState = _topState;
_topState = newTopState;
gameStatesCount++;
}
}
void GameStateStack::PopGameState()
{
if (_topState == NULL)
std::cout << "Error: no gamestates available to pop";
else
{
node * old = _topState; // HERE
_topState = _topState->nextGameState;
delete(old);
gameStatesCount--;
}
}
std::string GameStateStack::CurrentGameState()
{
node *temp; // HERE
temp = _topState;
return temp->gameState;
}
void GameStateStack::Destory()
{
node *abc; // HERE
delete _topState;
delete abc->nextGameState;
}
Here is how your stack could be implemented using a std::unique_ptr. Note the use of std::move() to re-assign the std::unique_ptr leaving the original pointing at nothing.
Also, instead of if(topState == NULL) I have used the more idiomatic if(topState). A std::unique_ptr returns true if it points somewhere or false if it does not.
Also standard C++ dictates that we should not begin variable names with a leading _.
#include <string>
#include <memory>
#include <iostream>
struct node
{
std::string gameState;
std::unique_ptr<node> nextGameState;
~node()
{
std::cout << "deleting: " << gameState << '\n';
}
};
class GameStateStack
{
// should not use _ to begin variable names in std C++
std::unique_ptr<node> topState;
int gameStatesCount;
public:
GameStateStack();
void PushGameState(std::string gameStateName);
void PopGameState();
std::string CurrentGameState();
void Destory();
};
GameStateStack::GameStateStack()
: gameStatesCount(0) // initialize here
{
//topState = NULL; // no need to initialize unique_ptr
//gameStatesCount = 0; // not here
}
void GameStateStack::PushGameState(std::string gameStateName)
{
std::unique_ptr<node> newTopState(new node);
newTopState->gameState = gameStateName;
newTopState->nextGameState = std::move(topState);
topState = std::move(newTopState);
gameStatesCount++;
}
void GameStateStack::PopGameState()
{
if(!topState)
std::cout << "Error: no gamestates available to pop";
else
{
topState = std::move(topState->nextGameState);
gameStatesCount--;
}
}
std::string GameStateStack::CurrentGameState()
{
if(topState)
return topState->gameState;
return "error: nothing on stack"; // error
}
void GameStateStack::Destory()
{
// deleting topState will first destroy the pointed to
// node's own unique_ptr<node> nextGameState
// which in turn will first delete its own nextGameState etc...
topState.reset();
}
int main()
{
GameStateStack stack;
std::cout << "\ndestroy test" << '\n';
stack.PushGameState("a");
stack.PushGameState("b");
stack.PushGameState("c");
stack.PushGameState("d");
stack.PushGameState("e");
stack.PushGameState("f");
stack.Destory();
std::cout << "\npush-pop test" << '\n';
stack.PushGameState("a");
stack.PushGameState("b");
stack.PushGameState("c");
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
stack.PushGameState("d");
stack.PushGameState("e");
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
}
Here an unique_ptr is perfectly fine, especially if you return the CurrentGameState by value as you are doing.
Your top should be a unique_ptr<node>& but since there will be no state at the beginning you could use a std::reference_wrapper to wrap it.
Of course if you plan to return a game state by reference or pointer things will change, because popping a state would invalidate the contained state (unless it's dynamically allocated and then set).
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
using namespace std;
struct delete_ptr
{
template<typename T>
void operator()(T*& t)
{
delete t;
t = 0;
}
};
struct is_null_ptr
{
template<typename T>
bool operator()(T*& t)
{
return t == 0;
}
};
struct A
{
static void removeDead(A*& a)
{
if(a and a->dead)
delete_ptr()(a);
}
static void killSome(A* a)
{
if(a and a->isDead() == false and rand()%100 == 0)
{
static int counter = 0;
cout << "Kill___" << ++counter << endl;
a->kill();
}
}
static void reviveSome(A* a)
{
if(a and a->isDead() and rand()%3 == 0)
{
static int counter = 0;
cout << "Revive___" << ++counter << endl;
a->revive();
}
}
A():dead(false)
{
}
virtual ~A()
{
static int counter = 0;
cout << "Dtor___" << ++counter << endl;
}
bool isDead(){return dead;}
void kill(){dead = true;}
void revive(){dead = false;}
bool dead;
};
int main()
{
srand(time(0));
vector<A*> as;
for(int i = 0; i < 200; ++i)
{
A* a = new A;
as.push_back(a);
}
for_each(as.begin(),as.end(),A::killSome);
for_each(as.begin(),as.end(),A::reviveSome);
for_each(as.begin(),as.end(),A::removeDead);
as.erase( std::remove_if(as.begin(),as.end(),is_null_ptr()),as.end());
cout << as.size() << endl;
for_each(as.begin(),as.end(),delete_ptr());
as.clear();
return 0;
}
It allocates them, and prints the right output but I'm not sure this is the right thing I'm doing. I was just trying to use pointers in a vector and delete them when a certain condition happens, without using boost or c++11.
So what do you think about it?
Since the only smart pointer present in the current STL (auto_ptr) cannot be used in containers, I would say your way is a good one under the given conditions.
You could think about implementing your own unique_ptr or shared_ptr however.
PS: There are many reasons to use pointers instead of the actual objects in a container, one is polymorphism. Another one is that the actual objects are already stored somewhere else (think of an index structure to already stored objects).
What is the best way to count the total number of objects created in both stack and heap for different classes. I know that in C++ new and delete operators can be overloaded and hence in the default constructor and destructor the object count can be incremented or decremented as and when the objects get created or destroyed.
Further if i am to extend the same thing for object counting of objects of different classes, then i can create a dummy class and write the object count code in that class and then when i create any new class i can derive it from the Dummy class.
Is there any other optimal solution to the same problem.
then i can create a dummy class and write the object count code in that class and then when i create any new class i can derive it from the Dummy class.
Yes, but since each class needs its own count, you have to make a base class template and use the curiously recurring template pattern (CRTP):
template <class Derived>
class InstanceCounter
{
static int count;
protected:
InstanceCounter()
{
++count;
}
~InstanceCounter()
{
--count;
}
public:
static int instance_count()
{
return count;
}
};
template <class Derived>
int InstanceCounter<Derived>::count = 0;
class Test : public InstanceCounter<Test>
{
};
int main()
{
Test x;
std::cout << Test::instance_count() << std::endl;
{
Test y;
Test z;
std::cout << Test::instance_count() << std::endl;
}
std::cout << Test::instance_count() << std::endl;
}
The way the object is created in stack and heap is different.
The new operator is used create an object in heap, and normal object declaration will create an object in stack.
So by overloading an new operator we can count the object created in heap.
static variable can be used to count the objects.
To find the no of objects created on Heap and Stack. To create the object on the heap we use new so override the new and delete keywords to keep track of the counter.
class Test
{
static int heapcount;
static int stackcount;
public:
static int GetHeapCount()
{
return heapcount;
}
static int GetStackCount()
{
//The objects which are created on heap also will call constructor and increment the stack count, so remove the objects that are created on heap to get stack count
return stackcount - heapcount;
}
Test()
{
++stackcount;
}
~Test()
{
--stackcount;
}
void* operator new(size_t size)
{
++heapcount;
void * p = malloc(sizeof(Test));
return p;
}
void operator delete(void* p)
{
--heapcount;
free(p);
}
void operator=(Test const& obj)
{
int x = 0;
}
};
int Test::heapcount = 0;
int Test::stackcount = 0;
int main()
{
{
Test t;
Test t2;
Test* t1 = new Test();
std::cout << "HeapCount = " << Test::GetHeapCount() << std::endl;//HeapCount = 1 (t1)
std::cout << "StackCount = " << Test::GetStackCount() << std::endl;//StackCount = 2 (t,t2)
delete t1;
}
//As all the objects are deleted so count must be zero, stack objects will be removed when goes out of scope
std::cout << "HeapCount = " << Test::GetHeapCount() << std::endl;//HeapCount = 0
std::cout << "StackCount = " << Test::GetStackCount() << std::endl;//StackCount=0
{
Test t[3];
Test* t2 = new Test();
Test* t3 = new Test();
std::cout << "HeapCount = " << Test::GetHeapCount() << std::endl;//HeapCount = 2 (t2,t3)
std::cout << "StackCount = " << Test::GetStackCount() << std::endl;//StackCount = 3 (t[3])
}
//Two heap objects are not deleted, but stack objects has been cleaned
std::cout << "HeapCount = " << Test::GetHeapCount() << std::endl;//HeapCount = 2
std::cout << "StackCount = " << Test::GetStackCount() << std::endl;//StackCount = 0
}
I am trying ot add a function template that will print if it contains precision values or valves and the value. The rest of the program works except this function. I am not sure what I am doing wrong but the error I recieve is:
error C2784: 'void printInstrumentDetail(const I *const )' : could not deduce template argument for 'const I *const ' from 'std::vector<_Ty>'
#include <iostream>
#include <vector>
#include <iomanip>
#include <string>
#include "Instruments.h"
#include "Brass.h"
#include "Strings.h"
using namespace std;
//template<typename I> <---Problem
//void printInstrumentDetail(const I * const a)
//{
// for (size_t i = 0; i < 6; i ++)
// {
// cout << "The details for " << a[i]->getName()
// << ": " << a[i]->print();
// }
//}
int main()
{
double total = 0;
Strings violin("Violin", 553.90, 3);
Strings cello("Cello", 876.45, 3);
Strings viola("Viola", 200.50, 23);
Brass tuba("Tuba", 1400.10, 1.23);
Brass trumpet("Trumpet", 500.00, 4.32);
Brass sax("Sax", 674.78, .99);
vector <Instruments *> band(6);
band[0] = &violin;
band[1] = &tuba;
band[2] = &cello;
band[3] = &trumpet;
band[4] = &viola;
band[5] = &sax;
cout << fixed << setprecision(2);
cout << "The instruments in the band are:\n";
//Get name and cost of each
for (size_t i = 0; i < 6; i ++)
{
cout << band[i]->getName() << " $"
<< band[i]->getCost() << endl;
}
cout << "\nThen band is warming up..." << endl;
//Get descrition of how sound is made of each
for (size_t i = 0; i < 6; i ++)
{
cout << "This " << band[i]->getName()
<< " makes sounds by " ;
band[i]->playSound();
}
cout << "\nTotal cost of the band is: $" ;
//Get total cost of all instruments
for (size_t i = 0; i < 6; i ++)
{
total = band[i]->getCost() + total;
}
cout << total << endl;
//printInstrumentDetail(band); <--Problem
return 0;
}
Here's the base class:
#ifndef INSTRUMENTS_H
#define INSTRUMENTS_H
#include <string>
using namespace std;
class Instruments
{
public:
Instruments(string, double);
void setName(string);
virtual string getName();
void setCost(double);
virtual double getCost();
virtual void print();
virtual void playSound();
private:
string name;
double cost;
};
#endif
#include <iostream>
#include "Instruments.h"
using namespace std;
Instruments::Instruments(string n, double c)
{
name = n;
cost = c;
}
void Instruments::setName(string n)
{
name = n;
}
string Instruments::getName()
{
return name;
}
void Instruments::setCost(double c)
{
cost = c;
}
double Instruments::getCost()
{
return cost;
}
void Instruments::print()
{
}
void Instruments::playSound()
{
//empty
}
Derived class Bass:
#ifndef BRASS_H
#define BRASS_H
#include <string>
#include "Instruments.h"
using namespace std;
class Brass : public Instruments
{
public:
Brass(string, double, double);
void setPrecisionValue(double);
double getPrecisionValue();
void print() ;
void playSound();
private:
double precision;
string sound;
};
#endif
#include <iostream>
#include "Brass.h"
using namespace std;
Brass::Brass(string n, double c, double p)
:Instruments(n, c)
{
precision = p;
}
void Brass::setPrecisionValue(double p)
{
precision = p;
}
double Brass::getPrecisionValue()
{
return precision;
}
void Brass::print()
{
cout << getPrecisionValue() << endl;
}
void Brass::playSound()
{
cout << "blowing in a mouthpiece." << endl;
Instruments::playSound();
}
Derived class Strings:
#ifndef STRINGS_H
#define STRINGS_H
#include <string>
#include "Instruments.h"
using namespace std;
class Strings : public Instruments
{
public:
Strings(string, double, int);
void setValves(int);
int getValves();
void print();
void playSound();
private:
int valves;
};
#endif
#include <iostream>
#include "Strings.h"
using namespace std;
Strings::Strings(string n, double c, int v)
:Instruments(n, c)
{
valves = v;
}
void Strings::setValves(int v)
{
valves = v;
}
int Strings::getValves()
{
return valves;
}
void Strings::print()
{
cout<< getValves() << endl;
}
void Strings::playSound()
{
cout << "striking with a bow." << endl;
Instruments::playSound();
}
Well, the problem is that your template requires a pointer:
template<typename I>
void printInstrumentDetail(const I * const a);
but you're giving it a vector, not a pointer:
vector <Instruments *> band(6);
...
printInstrumentDetail(band);
You can hack your way around this by passing a pointer to the printInstrumentDetail function, like so:
printInstrumentDetail(&band[0]);
But really, you'd be much better off modifying printInstrumentDetail to take a container or a pair of iterators:
template <typename ContainerT>
void printInstrumentDetail(const ContainerT& a)
or
template <typename IteratorT>
void printInstrumentDetail(IteratorT first, IteratorT last)
with the appropriate modifications to the definition of the function.
Pass the pointer to vector
printInstrumentDetail(&band);
and inside printInstrumentDetail
(*a)[i]->getName();
Well, first off I don't believe you can pass a vector as a const * I const at
printInstrumentDetail(band);
Vector cannot be just cast to a pointer. One working solution would be something like:
template <typename T>
void printInstrumentDetail( const std::vector<T*>& band )
{
for ( size_t i = 0; i < band.size(); ++i )
cout << "The details for " << band[i]->getName()
<< ": " << band[i]->print();
}
And there are many others, including iterators, functors, STL algorithms, etc.
You are trying to pass an object to an interface that wants a pointer.
void printInstrumentDetail(const I * const a)
Convert this to a reference.
void printInstrumentDetail(I const I& a)
But to conform to the pattern that is common in C++. You should pass the beginning and end of the sequence as parameters. ie change your function to take itertors rather than a pointer.
Instead of passing the pointer:
printInstrumentDetail(const I * const a)
you can pass the reference:
printInstrumentDetail(const I& a)
Everything else stays unchanged.
First of all, there seems to be no reason for PrintInstrumentDetail to be a template at all -- it works with pointers to the base class, and unless you're likely to have other types with getName() and print() members to which it might be applied, it can/could/should just work with pointers to the base class.
Second, I'd think hard about changing how you do the job. Instead of a member function in each Instrument, and PrintInstrumentDetail to loop over all the instruments, I'd think hard about defining operator<< for Instrument, and using a standard algorithm to print out the details.
Looking at it, I think a few other things should change as well. First of all, unless you're dealing with really unusual instruments, the number of valves on a brass instrument is fixed forever -- so it should NOT have a SetValve() member. Rather, the number of valves should be set during construction, but not be open to change afterwards.
String instruments don't have valves at all (at least most normal ones don't), so they shouldn't have SetValves(), GetValves(), or anything else related to valves.
Likewise, unless you're doing something pretty unusual, the cost of an instrument can never change -- you paid what you paid, so the cost should be set during construction, and not open to later alteration.
Edit: one other thing: instead of hard-coding 6 everywhere, use band.size() to loop over all the instruments in the band.