Accessing methods after inheritance error - c++

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

Related

Classes: Instantiating Object Confusion

Below is code for a simple book list with a class to store book names and isbn numbers into an overloaded function using a vector. This program runs fine and I can test it by returning a specific name (or isbn) using an accessor function from my class.
Question: I tried calling (instantiating?) a constructor with parameters from my class but it would not work, so I commented it out. Yet I was still able to run the program without error. From my main below - //BookData bkDataObj(bookName, isbn);
From watching tutorials, I thought I always had to make an object for a specific constructor from a class that I needed to call? My program definitely still uses my overloaded constructor and function declaration BookData(string, int); without making an object for it in main first.
Thanks for any help or input on this matter.
Main
#include <iostream>
#include <string>
#include <vector>
#include "BookData.h"
using namespace std;
int main()
{
string bookName[] = { "Neuromancer", "The Expanse", "Do Androids Dream of Electric Sheep?", "DUNE" };
int isbn[] = { 345404475, 441569595, 316129089, 441172717 };
//BookData bkDataObj(bookName, isbn); //how did program run without instantiating object for class?
vector <BookData> bookDataArr;
int arrayLength = sizeof(bookName) / sizeof(string);
for (int i = 0; i < arrayLength; i++) {
bookDataArr.push_back(BookData(bookName[i], isbn[i]));
}
cout << "Book 4 is: " << bookDataArr[3].getBookNameCl(); //test if works
return 0;
}
BookData.h
#include <iostream>
#include <string>
using namespace std;
class BookData
{
public:
BookData();
BookData(string, int); //wasn't I supposed to make an object for this constructor in my main?
string getBookNameCl();
int getIsbnCl();
private:
string bookNameCl;
int isbnCl;
};
BookData.cpp
#include "BookData.h"
BookData::BookData() {
bookNameCl = " ";
isbnCl = 0;
}
BookData::BookData(string bookNameOL, int isbnOL) { //how did I use this function
bookNameCl = bookNameOL; //definition without an object in main?
isbnCl = isbnOL;
}
string BookData::getBookNameCl() { //can still return a book name
return bookNameCl;
}
int BookData::getIsbnCl() {
return isbnCl;
}

List or Array of Elements of different datatypes

I want to store 6 pointers to objects. But the Pointers can be in any order and point to different instances of (12) subclasses of one superclass, so they are possibly all of different types.
Arrays and such don't work, because the superclass is virtual.
Vectors and Tuples don't work, because the datatypes are of no specific order and are not known at compile time.
Im fairly new to C++ and I'm running out of Ideas.
Here some code to elaborate the problem:
baseclass{
getfoobar()=0;
}
subclass1{
getfoobar(){...}
}
subclass2{
getfoobar(){...}
}
---
#include <otherclasses.h>
memoryclass{
baseclass mem[6];
}
is basically what im trying.
You CAN create a vector of superclass pointers. It will achieve what you want, as it will call the overwritten function. This is of course assuming you are talking about inheritance, like:
#include <vector>
using type = ????;
class A {
virtual type foo() = 0;
}
class B : A {
type foo() override { ... }
}
class C : A {
type foo() override { ... }
}
int main(){
std::vector<A*> arr;
arr.push_back(new B);
arr.push_back(new C);
}
Now if I misunderstood and this doesn't work for some reason (i.e. they just share the function and are not actually related classes), you can do something like this, but it is not very nice:
#include <concepts>
#include <vector>
#include <functional>
using type = ?????;
template <class T> requires requires(T t){
{ t.foo() } -> std::same_as<type>;
}
std::function<type()> getFunction(T* t){
return [t](){ return t->foo(); };
}
int main(){
std::vector<std::function<type()>> arr;
arr.push_back(getFunction(new B));
arr.push_back(getFunction(new C));
}
I don't recommend this over the first option unless you have very good reason to do this.
Note: Since you didn't specify return type I winged it with ?????
Also: In the second you can replace template<class T> requires ... std::function<type()>, with just template<class T> std::function<type()>, if the compiler doesn't like #include <concepts>
You can try std::set<Superclass*>. Use pointers to your base superclass instead pointers to particular subclasses.
Actually I used std::shared_ptr<> smart pointer template to avoid raw memory management.
Example code:
#include <cstdlib>
#include <string>
#include <sstream>
#include <set>
#include <memory>
#include <iostream>
class baseclass {
public:
virtual std::string getfoobar() = 0;
};
typedef std::shared_ptr<baseclass> baseclass_ptr;
class subclass1 : public baseclass{
public:
std::string getfoobar() override {
return "from subclass1";
}
};
class subclass2 : public baseclass{
public:
std::string getfoobar() override {
return "from subclass2";
}
};
int main(int argc, char** argv) {
// Use current time as seed for random generator
std::srand(static_cast<unsigned>(std::time(nullptr)));
std::set<baseclass_ptr> container;
// Randomly generate number of elements
const int random_count = std::rand() % 10 + 1;
for (int i = 0; i < random_count; ++i) {
// Randomly create subclass1 or subclass2
if (std::rand() % 2) {
container.insert(std::make_shared<subclass1>());
}
else {
container.insert(std::make_shared<subclass2>());
}
}
// Iterate resulting container
std::cout << "size = " << container.size() << std::endl;
for (auto iterator : container) {
std::cout << "getfoobar(): " << iterator->getfoobar() << std::endl;
}
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.

C++: Passing a pointer of master to the worker

I am very new to pointers, so I have no idea what is going on with them.
I am trying to get a master class pass a pointer of itself to its worker/s, and I have no idea why it doesn't work.
#include <iostream>
#include <Windows.h>
using namespace std;
class BigOne {
public:
LittleOne workers[1] = {LittleOne(this)};
int increase = 0;
};
class LittleOne {
BigOne* master;
public:
LittleOne(BigOne*);
void Increment();
};
LittleOne::LittleOne(BigOne* upOne) {
master = upOne;
}
void LittleOne::Increment() {
master->increase++;
}
BigOne Outer;
int main() {
cout << Outer.increase << endl;
Outer.worker.Increment();
cout << Outer.increase << endl;
system("PAUSE");
}
This is my problem boiled down to its core components.
The problem isn't with pointers. It's mostly here:
class BigOne {
public:
LittleOne workers[1] = {LittleOne(this)};
int increase = 0;
};
When you define workers, what is LittleOne? How is it laid out in memory? How is it initialized? The compiler can't know, it hasn't seen the class definition yet. So you must flip the definitions around:
class BigOne;
class LittleOne {
BigOne* master;
public:
LittleOne(BigOne*);
void Increment();
};
class BigOne {
public:
LittleOne workers[1] = {LittleOne(this)};
int increase = 0;
};
The forward declaration allows us to define members that accept and return pointers. So the class LittleOne can have its definition written before BigOne. And now BigOne can define members of type LittleOne by value.
The issue is with forward declaration.
You can refer the following link for more details and explanation.
What are forward declarations in C++?

How do you call a class and its method when its stored in a pointer array

How do you use a pointer and call the class methods it points to?
For example:
Image *img[26];
Image IM = outputImage();
img[0] = &IM;
I want to call img[0], or IM's methods. I tried something like this but I received errors.
img[0].getPixel(0,1);
The error is "expression must have a class type"
Since you are using a pointer array, you must dereference it as a pointer.
img[0]->getPixel(0, 1);
And this:
Image IM = outputImage();
should be:
Image &IM = outputImage();
Assuming that outputImage() returns a reference.
you can use following two methods:
1) use -> operator to the member function.
#include<iostream>
using namespace std;
class myclass
{
public:
void printHello()
{
cout<<"hello from class"<<endl;
}
};
int main()
{
myclass *s[10];
myclass inst;
s[0]=&inst;
s[0]->printHello();
return 0;
}
2) use . after de-referencing the pointer.
#include<iostream>
using namespace std;
class myclass
{
public:
void printHello()
{
cout<<"hello from class"<<endl;
}
};
int main()
{
myclass *s[10];
myclass inst;
s[0]=&inst;
(*s[0]).printHello();
return 0;
}