Having trouble writing stack implementation c++ - c++

I am building a programming language interpreter, and I am currently working on writing the stack code. Write now the stack will only hold byte values, but it will be extended to hold other bytes as well. At the moment I am having trouble with casting between 'BaseObject' that all my stack objects extend and my jbyte class. Here is my current test code.
#include "stdafx.h"
#include <string>
#include <stack>
#include <iostream>
#include <Windows.h>
#include <stack>
using namespace std;
class BaseObject
{
public:
virtual string getIdentifier(){return "Not Implemented";}
};
class Stack
{
class jbyte : public BaseObject
{
private:
INT8 byteValue;
public:
jbyte(INT8 value)
{
byteValue = value;
}
INT8 getValue()
{
return byteValue;
}
};
private:
stack<BaseObject> objectStack;
public:
void pushByte(INT8 byteValue)
{
jbyte toPush(byteValue);
objectStack.push(toPush);
}
INT8 popByte()
{
if(objectStack.size() == 0)
{
cout<<"ERROR: Trying To Pop Value From Empty Stack\nPress Any Key To Continue...";
_gettch();
exit(1);
}
else
{
BaseObject& bo = objectStack.top();
jbyte& b = dynamic_cast<jbyte&>(bo);
}
}
};
int main()
{
Stack stack;
stack.pushByte(9);
stack.popByte();
while(true);
}
When I try to run this however, I get an Unhandled exception at at 0x75C4C41F in StackTests.exe: Microsoft C++ exception: std::bad_cast at memory location 0x0034F858.
I would like to know how to fix this problem, or if that is difficult, how I could rewrite the stack to work successfully.

When you objectStack.push(toPush), the jbyte part of toPush is sliced off and only the BaseObject part remains. That's why casting the BaseObject back to jbyte is no longer possible.

Related

Dependency Injection with Shared pointer instead of Singleton in C++

I am trying to implement 2 or more classes that are going to use the same shared memory through a wrapper class as a dependency.
My doubt: Can shared pointer substitute Singleton ?
Note: I am trying to avoid Singleton for unit-test purpose.
Below is sample code for reference. Is this implementation fine or violates any C++ Principles?
IShmWrapper.h
#pragma once
class IShmWrapper
{
public:
virtual bool writeToSharedMemory() = 0;
virtual bool readFromSharedMemory() = 0;
};
ShmWrapper.h
#include "IShmWrapper.h"
class ShmWrapper : public IShmWrapper
{
public:
bool writeToSharedMemory() override; //Write operation on shared memory
bool readFromSharedMemory() override;//Read operation on shared memory
};
ShmWrapper.cpp
#include "ShmWrapper.h"
bool ShmWrapper::writeToSharedMemory()
{
//Write operation on shared memory
}
bool ShmWrapper::readFromSharedMemory()
{
//Read operation on shared memory
}
ShmUserA.h
#include "IShmWrapper.h"
#include <memory>
class ShmUserA
{
private:
std::shared_ptr<IShmWrapper> m_shmWrapperA;
public:
ShmUserA(std::shared_ptr<IShmWrapper> shmWrapper);
};
ShmUserA.cpp
#include "ShmUserA.h"
ShmUserA::ShmUserA(std::shared_ptr<IShmWrapper> shmWrapper)
: m_shmWrapperA(std::move(shmWrapper))
{
// Do Additional initialization
}
ShmUserB.h
#include "IShmWrapper.h"
#include <memory>
class ShmUserB
{
private:
std::shared_ptr<IShmWrapper> m_shmWrapperB;
public:
ShmUserB(std::shared_ptr<IShmWrapper> shmWrapper);
};
ShmUserB.cpp
#include "ShmUserB.h"
ShmUserB::ShmUserB(std::shared_ptr<IShmWrapper> shmWrapper)
: m_shmWrapperB(std::move(shmWrapper))
{
// Do Additional initialization
}
Main.cpp
#include<iostream>
#include<IShmWrapper.h>
#include<ShmWrapper.h>
#include<ShmUserA.h>
#include<ShmUserB.h>
int main()
{
std::shared_ptr<IShmWrapper> shmInstance = std::make_shared<ShmWrapper>();
std::unique_ptr<ShmUserA> shmUserA = std::make_unique<ShmUserA>(shmInstance);
std::unique_ptr<ShmUserB> shmUserB = std::make_unique<ShmUserB>(shmInstance);
while(1)
{
//Do Processing of data for incoming requests
}
return 0;
}

C++ Pointer function to other class function

I need help with passing a function pointer on C++. I can't linkage one function for a class to other function. I will explain. Anyway I will put a code resume of my program, it is much larger than the code expose here but for more easier I put only the part I need to it works fine.
I have one class (MainSystem) and inside I have an object pointer to the other class (ComCamera). The last class is a SocketServer, and I want when the socket received any data, it sends to the linkage function to MainSystem.
ComCamera is a resource Shared with more class and I need to associate the functions ComCamera::vRecvData to a MainSystem::vRecvData or other function of other class for the call when receive data and send de data to the function class associate.
Can Anyone help to me?
EDDITED - SOLUTION BELOW
main.cpp
#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include <exception>
#include <unistd.h>
using std::string;
class ComCamera {
public:
std::function<void(int, std::string)> vRecvData;
void vLinkRecvFunction(std::function<void(int, std::string)> vCallBack) {
this->vRecvData = vCallBack;
}
void vCallFromCamera() {
this->vRecvData(4, "Example");
};
};
class MainSystem {
private:
ComCamera *xComCamera;
public:
MainSystem(ComCamera *xComCamera) {
this->xComCamera = xComCamera;
this->xComCamera->vLinkRecvFunction([this](int iChannelNumber, std::string sData) {vRecvData(iChannelNumber, sData); });
}
void vRecvData(int iNumber, string sData) {
std::cout << "RECV Data From Camera(" + std::to_string(iNumber) + "): " << sData << std::endl;
};
};
int main(void) {
ComCamera xComCamera;
MainSystem xMainSystem(&xComCamera);
xComCamera.vCallFromCamera();
return 0;
}
Output will be:
MainSystem RECV Data From Camera(4): Example
You can have ComCamera::vRecvData be of type std::function<void(int, std::string)> and then have ComCamera::vLinkRecvFunction() be like this:
void ComCamera::vLinkRecvFunction(std::function<void(int, std::string)> callBack)
{
this->vRecvData = callBack;
}
and have MainSystem constructor be like this:
MainSystem::MainSystem(ComCamera *xComCamera)
{
using namespace std::placeholders;
this->xComCamera = xComCamera;
this->xComCamera->vLinkRecvFunction([this](int iNumber, std::string sData){vRecvData(number, sData);});
}
Still though the original question has way too much code to go through friend.
Here what you want :
#include<iostream>
using std::cout;
class A; //forward declare A
class B{
public:
void (A::*ptr)(int x); //Only declare the pointer because A is not yet defined.
};
class A{
public:
void increase_by(int x){
a+=x;
} // this function will be pointed by B's ptr
int a = 0; // assume some data in a;
B b; // creating B inside of A;
void analyze(int y){
(*this.*(b.ptr))(y);
} // Some function that analyzes the data of A or B; Here this just increments A::a through B's ptr
};
int main(){
A a; // creates A
cout<<a.a<<"\n"; // shows initial value of a
a.b.ptr = &A::increase_by; // defines the ptr that lies inside of b which inturns lies inside a
a.analyze(3); // calls the initialize method
(a.*(a.b.ptr))(3); // directly calls b.ptr to change a.a
cout<<a.a; // shows the value after analyzing
return 0;
}
Output will be :
0
6
I still don't get why would you do something like this. But maybe this is what you wanted as per your comments.
To know more read this wonderful PDF.

Undefined Reference to 'vtable for class'

I am implementing a Visitor class in C++ that generates XML output for a parse tree.
When I compile with Clion on Windows the code compiles but when it runs after it outputs what is expected it crashes. The error code is this
Process finished with exit code -1073741819 (0xC0000005)
When I try to compile using gcc (without Clion) I get the error message
Undefined Reference to 'vtable for PrintXMLVisitor'.
My code is the following. I have distilled it down to the least amount the produces the error
ASTNode.h
#ifndef MINILANG_ASTNODE_H
#define MINILANG_ASTNODE_H
#include <memory>
class Visitor;
class ASTNode {
public:
virtual void accept(std::shared_ptr<Visitor> visitor) = 0;
};
#endif //MINILANG_ASTNODE_H
ASTTypeNode.h
#ifndef MINILANG_ASTTYPENODE_H
#define MINILANG_ASTTYPENODE_H
#include "ASTNode.h"
class ASTTypeNode: public ASTNode {
public:
enum Type {Real, Int, Bool, String};
ASTTypeNode(Type type);
Type getType() const;
void accept(std::shared_ptr<Visitor> visitor) override;
private:
Type type;
};
#endif //MINILANG_ASTTYPENODE_H
ASTTypeNode.cpp
#include "ASTTypeNode.h"
#include "Visitor.h"
ASTTypeNode::ASTTypeNode(ASTTypeNode::Type type)
: type(type)
{
}
ASTTypeNode::Type ASTTypeNode::getType() const {
return type;
}
void ASTTypeNode::accept(std::shared_ptr<Visitor> visitor) {
visitor->visit(std::shared_ptr<ASTTypeNode>(this));
}
Visitor.h
#ifndef MINILANG_VISITOR_H
#define MINILANG_VISITOR_H
#include <memory>
#include "ASTTypeNode.h"
class Visitor {
public:
virtual void visit(std::shared_ptr<ASTTypeNode> typeNode) = 0;
};
#endif //MINILANG_VISITOR_H
PrintXMLVisitor.h
#ifndef MINILANG_PRINTXMLVISITOR_H
#define MINILANG_PRINTXMLVISITOR_H
#include "Visitor.h"
class PrintXMLVisitor: public Visitor {
public:
void visit(std::shared_ptr<ASTTypeNode> typeNode) override;
};
#endif //MINILANG_PRINTXMLVISITOR_H
PrintXMLVisitor.cpp
#include "PrintXMLVisitor.h"
#include <iostream>
void PrintXMLVisitor::visit(std::shared_ptr<ASTTypeNode> typeNode) {
std::string typeName;
switch(typeNode->getType())
{
case ASTTypeNode::Type::Real:
typeName = "Real";
break;
case ASTTypeNode::Type::Int:
typeName = "Int";
break;
case ASTTypeNode::Type::Bool:
typeName = "Bool";
break;
case ASTTypeNode::Type::String:
typeName = "String";
break;
default:
typeName = "Error";
exit(22);
}
std::cout << "<TypeNode>" << typeName << "</TypeNode>" << std:: endl;
}
main.cpp
#include <iostream>
#include "Lexer.h"
#include "ASTTypeNode.h"
#include "PrintXMLVisitor.h"
int main() {
ASTTypeNode astTypeNode (ASTTypeNode::Type::Int);
astTypeNode.accept(std::make_shared<PrintXMLVisitor>());
return 0;
}
Your crafting a shared pointer that isn't dynamic. Specifically,
void ASTTypeNode::accept(std::shared_ptr<Visitor> visitor) {
visitor->visit(std::shared_ptr<ASTTypeNode>(this)); // <=== HERE
}
The this in that statement refers to:
int main()
{
ASTTypeNode astTypeNode (ASTTypeNode::Type::Int); // <== this object
astTypeNode.accept(std::make_shared<PrintXMLVisitor>());
return 0;
}
Changing toolchains isn't going to fix this problem you have options, the two most obvious being:
Stop using a std::shared_ptr for the visit parameter.
Manage all ASTNodeType instances a requiring being std::shared_ptr managed and share from this using the std:enable_shared_from_this capabilities of the standard library.
The former of these is obvious (or at least it is now), so I'll not discuss it further. The latter is not necessarily trivial, as it mandates any instances of your underlying class that utilize shared_from_this must be managed by std::shared_ptr wrappers. I.e., there are no concrete constructions like you're currently doing in main(). This could have significant impact on your overall code base, so choose this carefully.
An example of how the above would work in your case:
First, change the derivation chain of ASTNodeType to look like this:
class ASTTypeNode
: public ASTNode
, public std::enable_shared_from_this<ASTTypeNode> // ADDED
Next, utilize shared_from_this as follows:
void ASTTypeNode::accept(std::shared_ptr<Visitor> visitor)
{
visitor->visit(shared_from_this()); // HERE
}
And finally, honor the warrant you've made that ASTNodeType instances are shared-ptr managed by doing this:
int main()
{
std::shared_ptr<ASTTypeNode> astTypeNode = std::make_shared<ASTTypeNode>(ASTTypeNode::Type::Int);
astTypeNode->accept(std::make_shared<PrintXMLVisitor>());
return 0;
}
That should work. Read more about the things used in the above code here:
std::enable_shared_from_this
std::enable_shared_from_this::shared_from_this
As I said, all of this is to facilitate using a std::shared_ptr from an object given only a this pointer. If you can remove that requirement in the first place, it may be an easier path to take, and I would consider that first.

C++ Pointer crashes (Uninitialized)

It seems this problem is the so-called dangling pointer problem. Basically I'm trying to parse a pointer into a function (that stores the pointer as a global variable) inside a class, and I want the pointer to be stored in that class and can be used now and then. So from inside the class, I can manipulate this pointer and its value which is outside of the class.
I simplified the code and re-created the situation as the following:
main.cpp
#include <iostream>
#include "class.h"
using namespace std;
void main() {
dp dp1;
int input = 3;
int *pointer = &input;
dp1.store(pointer);
dp1.multiply();
}
class.h
#pragma once
#include <iostream>
using namespace std;
class dp {
public:
void store(int *num); // It stores the incoming pointer.
void multiply(); // It multiplies whatever is contained at the address pointed by the incoming pointer.
void print();
private:
int *stored_input; // I want to store the incoming pointer so it can be used in the class now and then.
};
class.cpp
#include <iostream>
#include "class.h"
using namespace std;
void dp::store(int *num) {
*stored_input = *num;
}
void dp::multiply() {
*stored_input *= 10;
print();
}
void dp::print() {
cout << *stored_input << "\n";
}
There is no compile error but after running it, it crashes.
It says:
Unhandled exception thrown: write access violation.
this->stored_input was 0xCCCCCCCC.
If there is a handler for this exception, the program may be safely continued.
I pressed "break" and it breaks at the 7th line of class.cpp:
*stored_input = *num;
It is not a dangling pointer, but a not initialized, you probably want:
void dp::store(int *num) {
stored_input = num;
}

Accessing methods after inheritance error

I am using inheritance for my code. ChangeRequest is my base class. The code is as follows.
ChangeRequest.h
#include <iostream>
#include <string>
using namespace std;
class ChangeRequest
{
int swapDay;
int newDay;
public:
void setSwapDay(int newDay);
int getSwapDay();
void setNewDay(int newDay);
int getNewDay();
};
ChangeRequest.cpp
#include "ChangeDutyRequest.h"
void ChangeRequest::setSwapDay(int newDay)
{
swapDay = newDay;
}
int ChangeRequest::getSwapDay()
{
return swapDay;
}
void ChangeRequest::setNewDay(int day)
{
newDay = day;
}
int ChangeRequest::getNewDay()
{
return newDay;
}
The code below is for the derived class. SwapDuty
SwapDuty.h
#include <iostream>
#include <string>
#include "ChangeRequest.h"
using namespace std;
class SwapDuty: public ChangeRequest
{
string requester;
public:
void setRequester(string member);
string getRequester();
};
SwapDuty.cpp
#include "SwapDuty.h"
void SwapDuty::setRequester(string member)
{
requester = member;
}
string SwapDuty::getRequester()
{
return requester;
}
when I compile and access the requester attribute using getRequester(). I get the following error.
'class ChangeRequest' has no member named 'getRequester'
This is how I used my code
Can someone please tell me what I am doing wrong? Thanks in advance
SwapDuty newSwapDutyRequest;
for(int i = 0; i < tempList.size(); i++ )
{
if(tempList[i].getPersonToPerform().getName() == loginMember)
{
newSwapDutyRequest.setRequester(loginMember);
newSwapDutyRequest.setSwapDay(swapDay);
newSwapDutyRequest.setNewDutyDay(daySwapWith);
break;
}
}
changeList.push_back(newSwapDutyRequest);
cout << changeList[1].getRequester() << endl;
What is type of changeList?
Although you have created an object of the derived class, I suspect that you are pushing it into the container of the base class. Possibly you are getting few warnings before this error as well, because of pushing derived object into the container of type base.
If you want to make a container of base class and push in the derived class objects you need to work with the pointers to the objects not the objects themselves.
Where is your class ChangeDutyRequest? You don't show it. Maybe you forgot to inherit it from the correct base or invoke it incorrectly?
Show fuller code sample