Use default value of Subclass method in an array of Base class - c++

Is there any way that cout << a[0]->function(); can give a 5 instead?
At the moment, it takes the default value of the base class and runs the method of the subclass.
But I want it to run the method of the subclass and take the default value of the subclass.
class Basis
{
public:
virtual int function(int i = 1) { return 2; }
};
class Sub : public Basis
{
public:
int function(int i = 5) override { return i; }
};
int main()
{
Basis* a[2];
a[0] = new Sub();
cout << a[0]->function(); //gives 1
}

Your code is calling function() via a Basis* pointer, so it is going to use the default value defined by Basis, there is no way for Sub to override that. Calling function() via a Sub* pointer would use the default value defined by Sub instead.
So, given the code you have shown, the easiest way I can think of doing what you are asking for is to use function overloads, eg:
class Basis
{
public:
virtual int function() { return function(1); }
virtual int function(int i) { return 2; }
};
class Sub : public Basis
{
public:
int function() override { return function(5); }
int function(int i) override { return i; }
};
int main()
{
Basis* a[2];
a[0] = new Basis();
a[1] = new Sub();
cout << a[0]->function(); //gives 2
cout << a[1]->function(); //gives 5
}

Related

Can you make a bool return 1 if a variable is of a certain type?

class A {
protected:
int a;
public:
int getA() const
{
return a;
}
};
class B : public A
{
private:
int b;
public:
int getB() const
{
return b;
}
};
class C
{
private:
int c;
A* obj;
public:
C()
{
obj = new A[5];// obj is initialized with some values in the constructor, but i won't do it here
}
void f()
{
c += obj[0].getB();
}
~C()
{
delete obj;
}
};
The problem I am facing right now is that i want the f function to add to the variable c the value of b from the object obj[0] if the type of obj[0] is B. But if the obj[0] is A and not B I dont want anything to happen.
Is there a bool that would be 1 if a certain variable is a certain type?
I know i could overload the f function and make it take a parameter the B obj[0] and another one that takes as a paramter the A obj[0], the last function having an empty body, but i was wondering if there is a more simple/efficient way of doing it.
I have bee asked to provide an example of where I would need this specific solution so here it is
class Item
{
protected:
std::string Name;
unsigned long long Number;
bool Placeable;
};
class Tool : public Item
{
private:
long double AttackDamage;
long double AttackSpeed;
public:
long double getAttackDamage() const
{
return this->AttackDamage;
}
long double getAttackSpeed() const
{
return this->AttackSpeed;
}
};
class Mob
{
protected:
Item* Inventory;
unsigned long long InventorySize;
unsigned long long MainHand;
std::string Name;
long double AttackDamage;
long double AttackSpeed;
public:
Mob(unsigned long long n)
{
this->AttackDamage = 1;
this->AttackSpeed = 0.5;
this->InventorySize = n;
this->Inventory = new Item[this->InventorySize];
for (int i = 0; i < this->InventorySize; ++i)
this->Inventory[i] = e; // e in empty slot, like a 0 initializer for integers
this->MainHand = 0;
}
void setStats()
{
this->AttackDamage += this->Inventory[this->MainHand].getAttackDamage();
this->AttackSpeed += this->Inventory[this->MainHand].getAttackSpeed();
}
~Mob()
{
delete Invenory;
}
};
The method i need help with is void SetStats() in Mob. I want the function to only update the values of AttackDamage and AttackSpeed if the item at MainHand position is a Tool. Otherwise i dont want any updates. I could add stas to the Item class like AttackDamage and AttackSpeed and set them to 0 which would make no issue but if i would be working on a more serious project i would have more stats than AttackDamage and Speed and there would be a lot of unnecesarry memory.
This is just a fraction of the code, like not all variables are initialized and there might be some things i forgot to paste
You need at least one virtual function in the base class, otherwise there is no polymorphism. The canonical way is to define a virtual destructor:
class A {
// ...
virtual ~A() = default;
};
To use polymorphism, you can't have value types. You need pointers or references. So instead of A obj, you'd need to use A* obj. You then try to dynamic_cast obj to a B* pointer. If obj is indeed pointing to a B, the cast succeeds and returns a valid B* pointer you can use. If obj is not pointing to a B, the cast fails and returns a null pointer:
class C {
private:
int c;
A* obj;
public:
void func()
{
if (auto casted_obj = dynamic_cast<B*>(obj)) {
c += casted_obj->getB();
}
}
};

Why is this program of hybrid inheritance giving wrong output?

In this program, I am trying to inculcate hybrid inheritance in this program but this is giving wrong output. I have taken arithmetic as base class and add,sub,mul,div as its derived classes.
And then I have derived a class result using add,sub,mul,div as base classes. I have tried all the data types but with all it gives wrong or zero output.
#include "iostream"
using namespace std;
class arithmetic
{
public:
float var1,var2;
void introduce()
{
cout<<"This program will perform arithmetic on two variables"<<endl
<<"Enter the first variable: ";
cin>>var1;
cout<<"Enter the second variable: ";
cin>>var2;
}
};
class add:public arithmetic
{
protected:
float res_add;
public:
void show_add()
{
res_add=var1+var2;
cout<<"Addition of those variables gives "<<res_add<<endl;
}
};
class sub:public arithmetic
{
protected:
float res_sub;
public:
void show_sub()
{
res_sub=var1-var2;
cout<<"Subtraction of those variables gives "<<res_sub<<endl;
}
};
class mul:public arithmetic
{
protected:
float res_mul;
public:
void show_mul()
{
res_mul=var1*var2;
cout<<"Multiplication of those variables gives "<<res_mul<<endl;
}
};
class div:public arithmetic
{
protected:
float res_div;
public:
void show_div()
{
res_div=var1/var2;
cout<<"Divison of those variables gives "<<res_div<<endl;
}
};
class result:public add, public sub,public mul,public div
{
public:
void showres()
{
cout<<"Arithmetic on the given two varibales gives us the following result:"<<endl;
}
};
int main()
{
result example;
arithmetic var;
var.introduce();
example.showres();
example.show_add();
example.show_sub();
example.show_mul();
example.show_div();
return 0;
}
You are creating two separate object var (base class object) and example ( derived class object). Initializing the var1 and var2 by calling the var.introduce() and calling the methods show_add(), show_sub() etc. in the example object, in example object var1 and var2 is not initialized. so whatever arithmetic operation you are calling is getting applied in the uninitialized var1 and var2 member variable of example object.
you don't need to create the base class object(var). call the intruduce() method from the example then it will start working fine.
Please go through the below sample code to understand the concept of virtual base class.
#include <iostream>
class A
{
public:
int i;
};
class B : virtual public A
{
public:
int j;
};
class C: virtual public A
{
public:
int k;
};
class D: public B, public C
{
public:
int sum;
};
int main()
{
D ob;
ob.i = 10; //unambiguous since only one copy of i is inherited.
ob.j = 20;
ob.k = 30;
ob.sum = ob.i + ob.j + ob.k;
std::cout << "Value of i is : "<< ob.i<<"\n";
std::cout << "Value of j is : "<< ob.j<<"\n";
std::cout << "Value of k is : "<< ob.k<<"\n";
std::cout << "Sum is : "<< ob.sum <<"\n";
return 0;
}
Output:
Value of i is : 10
Value of j is : 20
Value of k is : 30
Sum is : 60
Live Demo on coliru
If you want to avoid virtual inheritance and want something simpler, use composition.
For this, class result should contain objects of add, sub, mul and div.
The resulting code for result will look something like this:
class result:public arithmetic
{
public:
mul m;
add a;
sub s;
div d;
void assignvals()
{
m.var1 = var1; m.var2 = var2;
a.var1 = var1; a.var2 = var2;
s.var1 = var1; s.var2 = var2;
d.var1 = var1; d.var2 = var2;
}
void showres()
{
cout<<"Arithmetic on the given two variables gives us the following result:"<<endl;
}
};
The resulting code for main will look something like this:
int main()
{
result example;
example.introduce();
example.assignvals();
example.showres();
example.a.show_add();
example.s.show_sub();
example.m.show_mul();
example.d.show_div();
return 0;
}
Note: Some compilers will complain if div is used as a class name because it is also the name of a library function in C++. So you will have to change the name of this class.

How to transfer values set in privates of base class by an object of one derived class to an object of another derived class?

I have my main.cpp like this:
#include <iostream>
#include "curve1.h"
#include "curve2.h"
using namespace std;
int main()
{
Curve1 curve1Obj;
Curve2 curve2Obj;
curve1Obj.enterScores();
curve1Obj.calcAverage();
curve1Obj.output();
curve1Obj.curve();
curve1Obj.output(curve1Obj.new_getAverage1(), curve1Obj.new_getScore1());
curve2Obj.curve();
return 0;
}
Base class Score has two derived classes Curve1 and Curve2. There are two curve() functions, one is in Curve1 and other in Curve2 classes. getSize() returns the value of iSize.
My base class header score.h looks like this:
#ifndef SCORE_H
#define SCORE_H
class Score
{
private:
int *ipScore;
float fAverage;
int iSize;
public:
Score(
void enterScores();
void calcAverage();
void output();
void output(float, int*);
void setSize();
int getSize();
void setScore();
int *getScore();
float getAverage();
};
#endif
You can see that I have used curve1Obj to enter scores, calculate average and output. So if I call getSize() function with cuve1Obj, it gives the right size that I took from user in enterScores() function. Also the result is same if I call getSize() in score.cpp definition file in any of the functions (obviously).
.....
The problem is when I call curve() function of Curve2 class in main (line 23) with the object curve2Obj, it creates a new set of ipScore, fAverage and iSize (i think?) with garbage values. So when I call getSize() in curve() definition in curve2.cpp, it outputs the garbage.
.....
How can I cause it to return the old values that are set in curve1.cpp?
Here is my curve2.cpp
#include <iostream>
#include "curve2.h"
using namespace std;
void Curve2::curve()
{
cout << "getSize() returns: " << getSize() << endl; // out comes the garbage
}
Can I use a function to simply put values from old to new variables? If yes then how?
Well, basically your problem can't be easily solved the way it is.
Like you said:
1 - Don't use constructors of any type.
2 - Don't use vectors.
3 - Using dynamic new and delete etc. etc.
Use the constructors or stick with what G. Samaras and Richard Hodges said. You can only solve this that way.
There is limited information available here but I would say that your Score constructor has not initialised ipScore or iSize.
If you are hell-bent on using a pointer to a dynamically allocated array of ints for your score then at least null out the pointer in the constructor and test for null in the average function (i.e. no scores yet).
Better yet... use a std::vector of int for your scores.
Why are people still using new and delete? What the hell are they teaching in schools?
What I think you want is this:
#include <vector>
class Score {
public:
Score()
: _scores()
, _average(0)
{ }
void calcAverage() {
double total = 0;
if(auto s = _scores.size() > 0) {
for (const auto& v : _scores)
total += v;
total /= s;
}
_average = total;
}
virtual void curve() = 0;
protected:
// one of the few correct uses of 'protected' - giving limited access to data as interface to derived classes
const std::vector<double>& scores() const {
return _scores;
}
// or
std::vector<double> copyScores() const {
return _scores;
}
private:
// use doubles since you'll be doing floating point arithmetic
std::vector<double> _scores;
double _average;
};
class Curve1 : public Score {
public:
virtual void curve() override {
// custom curve function here
// written in terms of scores() or copyScores() if you want to make changes to the array
}
};
class Curve2 : public Score {
public:
virtual void curve() override {
// custom curve function here
// written in terms of scores();
}
};
You need to understand inheritance. Curve1 inherits from Score. Curve2 inherits from Score.
Now see this example:
#include <iostream>
class Base {
int x;
};
class A : public Base {
int a;
public:
void set_a(int arg) {
a = arg;
}
int get_a() {
return a;
}
};
class B : public Base {
int b;
public:
void set_b(int arg) {
b = arg;
}
int get_b() {
return b;
}
};
int main() {
A a_object;
a_object.set_a(4);
B b_object;
b_object.set_b(a_object.get_a());
std::cout << "a of a_object = " << a_object.get_a() << "\n";
std::cout << "b of b_object = " << b_object.get_b() << "\n";
return 0;
}
class A, has as members x and a. Class B has as members x and b.
When I create an instance of class A, I will two data members created internally, x and a.
When I create an instance of class A, I will two data members created internally, x and b.
But, the first x and the second are DIFFERENT. They are a different cell in the memory!
something like this:
class Score {
public:
Score()
: _scores(0)
, _size(0)
, _average(0)
{ }
// copy constructor
Score(const Score& rhs)
: _scores( new double[rhs._size] )
, _size(rhs._size)
, _average(rhs._average)
{
if (_size) {
for(int i = 0 ; i < _size ; ++i) {
_scores[i] = rhs._scores[i];
}
}
}
// ... and if copy constructor then always a copy operator
Score& operator=(const Score& rhs) {
// assignment in terms of copy constructor - don't repeat yourself
Score tmp(rhs);
swap(tmp);
return *this;
}
// pre c++11 we make our own swap.
// post c++11 we would make non-throwing move constructor and move-assignment operator
void swap(Score& rhs) {
// std::swap is guaranteed not to throw
std::swap(_scores, rhs._scores);
std::swap(_size, rhs._size);
std::swap(_average, rhs._average);
}
~Score()
{
delete[] _scores;
}
void calcAverage() {
double total = 0;
if(_size > 0) {
for (int i = 0 ; i < _size ; ++i)
total += _scores[i];
total /= _size;
}
_average = total;
}
virtual void curve() {};
private:
// use doubles since you'll be doing floating point arithmetic
double * _scores;
int _size;
double _average;
};
// rmember to override the copy operators and assignment operators of derived classes
// remember to call the base class's operator

C++ copying data from an abstract base class pointer?

Let's say you have this:
class foo {
public:
virtual int myFunc() = 0;
///...
virtual bool who() = 0; // don't want to implement this
};
class bar : public foo {
public:
int myFunc() {return 3;}
//...
bool who() {return true;} // don't want to implement this
};
class clam : public foo {
public:
int myFunc() {return 4;}
//...
bool who() {return false;} // don't want to implement this
};
int main() {
std::vector<foo*> vec (2, NULL);
vec[0] = new bar();
vec[1] = new clam();
// copy vec and allocate new ptrs as copies of the data pointed to by vec[i]
std::vector<foo*> vec2 (vec.size(), NULL);
for ( int i=0; i<vec.size(); ++i ) {
// obviously not valid expression, but it would be nice if it were this easy
//vec2[i] = new foo(*vec[i]);
// the hard way of copying... is there easier way?
if (vec[i]->who()) {
vec2[i] = new bar ( * static_cast<bar* >(vec[i]) ) ;
} else {
vec2[i] = new clam( * static_cast<clam*>(vec[i]) );
}
}
return 0;
}
What I want is some simple way of having the compiler look up in its bookkeeping and allocating/copying vec2[i] according to the stored type of *vec[i]. The workaround is to just make a virtual function which basically returns a value specifying what type *vec[i] is, then doing a conditional allocation based on that.
A common approach goes like this:
class foo {
public:
virtual foo* clone() = 0;
};
class bar : public foo {
public:
virtual bar* clone() { return new bar(*this); }
};
class clam : public foo {
public:
virtual clam* clone() { return new clam(*this); }
};
One way you can do it is by using a dynamic cast to determine type of an object such as done here (Finding the type of an object in C++). but the easiest way would probably be to use typeid.
(assuming you want to maintain your way of using type as a determiner, otherwise I would recommend Joachim's or Igor's as better alternatives :) )
you can use the dynamic_cast to downcast and test the type,
bar* pbar = dynamic_cast<bar*>(vec[i])
if (pbar) {
vec2[i] = new bar ( * static_cast<bar* >(vec[i]) ) ;
} else {
vec2[i] = new clam( * static_cast<clam*>(vec[i]) );
}
see for more info in dynamic_cast
http://www.cplusplus.com/doc/tutorial/typecasting/

Design problems in C++

I have a raw buffer which contains number of different structs(which I couldn't modify) which I planned to wrapped inside a class like below so that I could invoke the virtual Process based on the concrete type.
class Base{
public:
virtual void Process();
};
class DerivedA : public Base {
private:
char* structBuf;
public:
virtual void Process();
}
class DerivedB : public Base {
private:
char* structBuf;
public:
virtual void Process();
}
int main()
{
for(int i = 0 ; i < 10; i++)
{
Base* a = FactoryObject();
a->Process();
}
}
My question is some of the objects depent on each other. For example, let say derivedA data would be processed first and derivedB needs the data from derivedA.
How or where could I store the derivedA object in main() so that I could utilize it in derivedB?
How could I know which objects from factory is derivedA so that I could store it?
Add a constructor to DerivedB that takes a DerivedA parameter. Construct your DerivedB instance only after you processed your DerivedA instance, passing to DerivedB the DerivedA instance.
I think I'm understanding your question.
In main you would have your object that holds the data you want passed around. Have a derivedA public data object (or you can make it private and set it with a set function) and make derivedA.data = main's data. Then when derivedA does its stuff, the object in main will still point to it. Then you repeat the process by handing the data to derivedB with derivedB.data = main's data.
If you make char* structBuf; protected instead of private then all derived classes can access it. As it stands I'm not sure how you'll implement the process function in your derived classes.
It sounds like you're looking for some cache or data-store of already processed information. You could write a class to store this type specific info and then retrieve it in later calls to your virtual process functions. Something like:
class DataCache {
public:
void store( DerivedA* data );
void store( DerivedB* data );
std::list<DerivedA*>& getDerivedA();
std::list<DerivedB*>& getDerivedB();
}
Now your process function should take a reference to a DataCache object, so each call can store and get appropriately. DerivedB might implement process like:
DerivedB::process( DataCache& cache ) {
std::list<DerivedA*>& a_data = cache.getDerivedA();
//do something
cache.store( this );
}
I've interpreted your question as pertaining to reading in a file or stream which has a header section that sets out the subsequent instance definition sections.
#include <iostream>
class AbstractDataProcessor;
class ProcessorFactory
{
public:
static AbstractDataProcessor* create(const char id);
};
class AbstractDataProcessor
{
public:
AbstractDataProcessor() : next_(0) {}
virtual ~AbstractDataProcessor()
{
if(next_ != 0)
{
delete next_;
next_ = 0;
}
}
void process(const char* buf, int size)
{
process(buf, 0, size);
}
protected:
virtual int do_process(const char* buf, int start, int size) = 0;
void append(AbstractDataProcessor* chain)
{
if(next_ == 0)
{
next_ = chain;
}
else
{
next_->append(chain);
}
}
private:
void process(const char* buf, int start, int size)
{
int next_start = do_process(buf, start, size);
std::cout << "AbstractDataProcessor::process: start = " << start << " : size = " << size << " : next_start = " << next_start << std::endl;
if(next_ == 0 || next_start >= size)
{
return;
}
next_->process(buf, next_start, size);
}
AbstractDataProcessor* next_;
};
class HeaderProcessor : public AbstractDataProcessor
{
protected:
static const char header_sentinel = 'H';
virtual int do_process(const char* buf, int start, int size)
{
int current = start;
while(current < size && buf[current] != header_sentinel)
{
std::cout << "HeaderProcessor::do_process: buf[" << current << "] = " << buf[current] << std::endl;
AbstractDataProcessor* section_processor = ProcessorFactory::create(buf[current]);
if(section_processor != 0)
{
append(section_processor);
}
++current;
}
return current + 1;
}
};
class ElementProcessor : public AbstractDataProcessor
{
protected:
int do_process(const char* buf, int start, int size)
{
foo_ = static_cast<float>(buf[start]);
std::cout << "ElementProcessor::do_process: buf[" << start << "] = " << buf[start] << " : foo_ = " << foo_ << std::endl;
return start + (sizeof(float) / sizeof(char));
}
private:
float foo_;
};
AbstractDataProcessor* ProcessorFactory::create(char id)
{
std::cout << "ProcessorFactory::create: id = " << id << std::endl;
switch(id)
{
case 'h':
return new HeaderProcessor;
case 'e':
return new ElementProcessor;
default:
return 0;
}
}
int main(int argc, char** argv)
{
static const int buf_size = 6;
char testbuf[buf_size] = { 'e', 'H', 'x', '3', 't', '[' };
AbstractDataProcessor* testprocessor = ProcessorFactory::create('h');
testprocessor->process(testbuf, buf_size);
return 0;
}
its not the most elegant example, but it illustrates the idea of generating a linked list of processors that act on a single input stream of data. Each processor is capable of appending a new processor as appropriate, you could define another method "AbstractDataProcessor::insert" to allow for implementing a recursive delegation approach within each "do_process" method too. i haven't included any useful extraction methods, but it should be easy enough to walk the linked list and spit out pointers to something in main or wherever you need it.
You could do something like this:
class DerivedA;
class Base{
public:
virtual void Process();
protected:
static std::vector<DerivedA*> dependencies;
};
class DerivedA : public Base {
private:
char* structBuf;
public:
DerivedA() {
dependencies.push_back(this);
}
virtual void Process();
};
class DerivedB : public Base {
private:
char* structBuf;
public:
virtual void Process();
};
int main()
{
std::vector<Base*> allBase;
for(int i = 0 ; i < 10; i++) {
allBase.push_back(FactoryObject());
}
for(int i = 0 ; i < 10; i++) {
allBase[i]->Process();
}
return 0;
}
In short, while the objects are constructed the DerivedA ones are registering themselves in a static vector in Base, which means they are accessible in DerivedB once you are calling Process() on DerivedB types.
You must allow for all derived classes to be created before you can call Process. So, first map and create all and then map again and call Process(). This is of course not optimal since the base knows some about its inherited classes, but you insisted on having this factory pattern.
A better solution is to lift out the static vector from Base and store DerivedA elsewhere. But in the end it will boil down to you having to store DerivedA instances somewhere, and that registration should be done at construction, i.e. in the constructor of DerivedA. I dont know if a simple vector will do as registration, please modify this to suit your needs. For example you might want to look up DerivedA* with some identifier and need a hash or map instead.
Here comes dynamic_cast handy for you. If you have a Base* pointer, you try to do dynamic_cast. If it really is, then the result will be the DerivedA object. Else it is not DerivedA, returns NULL.
So in your main(),
Base* a = FactoryObject();
DerivedA *CheckObj= dynamic_cast<DerivedA*>(a);
DerivedA *AObj = NULL;
if(CheckObj)
{
AObj = CheckObj;
AObj->Process();
}
else
{
if(AObj)
{
AObj->Process();
CheckObj->Process();
}
}