C++ calling an inherited constructor - c++

I have a header file, "Item.h", which "Sword.h" inherits, like this:
#ifndef SWORD_H
#define SWORD_H
#include "Item.h"
class Sword: public Item {
public:
Sword(int damage);
~Sword();
};
#endif
My Item.h is this:
#ifndef ITEM_H
#define ITEM_H
class Item{
public:
int damage;
Item(int damage);
int GetDamage();
};
#endif
And then I have a file, "Sword.cpp", that I want to call the Item constructor from (this is the Item.cpp):
#include "Item.h"
Item::Item(int damage)
{
this->damage = damage;
}
int Item::GetDamage()
{
return damage;
}
I basically want Sword.cpp to be a child class of Item.cpp, so that I can use Item's functions, and set variables such as Damage from Sword.cpp. I've been told there is no way to inherit constructors in C++ though, so how could I do this? Some answers seem to use the explicit keyword, but I can never get it to work.
Any help please?

You can actually inherit constructors. It is all-or nothing though, you can't select which ones. This is how you do it:
class Sword: public Item {
public:
using Item::Item;
~Sword();
};
If you are stuck with a pre-C++11 compiler, then you need to declare the constructor and implement it yourself. This would be the implementation in Sword.cpp:
Sword::Sword(int damage) : Item(damage) {}

You don't inherit the constructor because the constructor has the same name as the class (and obviously parent and child must have different names). But you can use the parent's constructor in the child's constructor
Sword()
: Item(3) // Call the superclass constructor and set damage to 3
{
// do something
}

You can define the Sword constructor the following way
Sword(int damage) : Item( damage ) {}
Also it would be better if the destructor of Item were virtual and data member damage should have access control protected. For example
class Item{
protected:
int damage;
public:
Item(int damage);
virtual ~Item() = default;
int GetDamage();
};

You can call the parent's constructor from your derived class's constructor like this:
Sword(int damage):
Item(damage)
{
}

Related

C++ Inheritance (instantiating derived class inside base class)

class MainClass
{
string _ClassName;
public:
string MainClass(string _C)
{
_ClassName = _C;
}
SubClass s1;
};
class SubClass : public MainClass
{
public:
string Method_1()
{
return a;
}
string Method_2()
{
return a;
}
};
Why is SubClass s1 not working can someone tell me please what am i missing I'm new to OOP.
I want to instantiate SubClass object inside MainClass but it doesn't seems to work.
basically, my aim is to access SubClass functions when MainClass object is instantiated in Main method something like this:
int Main()
{
MainClass M1("test");
M1.s1.Method_1(); <--------- this
}
The first problem is, that the MainClass does not know a thing about SubClass when you're trying to instantiate the object.
You need to use a forward declaration and a pointer to make it work.
Header file:
class SubClass; //Forward declaration, allows pointer.
class MainClass
{
string _ClassName;
public:
MainClass(string _C); //No return type on constructor
~MainClass();
SubClass *s1; //Size: 4 Bytes on 32bit system
protected:
MainClass();
};
class SubClass : public MainClass
{
public:
string Method_1();
string Method_2();
};
CPP file:
#include "headerFile.h"
MainClass::MainClass(string _C) :
_ClassName(_C),
s1(new SubClass) //Class definition is now known.
{
}
MainClass::MainClass() : s1(nullptr) //Nullptr -> No new object, no infinite recursion.
{
}
MainClass::~MainClass()
{
delete s1; //Do not forget to clean up your pointer.
}
string SubClass::Method_1()
{
return "a";
}
string SubClass::Method_2()
{
return "a";
}
Call:
int main()
{
MainClass M1("test");
M1.s1->Method_1(); //-> to dereference the pointer.
}
The second problem, as Richard Critten has pointed out, is an infinite recursion, which will cause your program to crash very quickly.
Each time you instantiate a SubClass, you also create a subclass, which creates yet another MainClass etc.
To circumvent this, you'll need a protected constructor, which does NOT create the subclass member.
The third problem:
You are returning a in your methods, which suggests a variable.
If you meant to return 'a', you need to put them into quotation marks.
Finally, in order to get it to compile, you'll need to write Main with a small m (int main()), otherwise the linker will complain.
However, as Mr. 'Not a number' correctly stated, the above edits only make your code compile.
What you likely are actually after however would be using virtual functions, which can be overridden by sub classes to specialize the behavior.
An example code using actual inheritance:
Header file:
class MainClass
{
string _ClassName;
public:
MainClass(string _C); //No return type on constructor
virtual ~MainClass(); //All base classes that have at least one virtual method should also have a virtual destructor, even if it is empty.
virtual void doSomething();
};
class SubClass : public MainClass
{
public:
SubClass(string className);
void doSomething();
};
CPP file:
#include "headerFile.h"
#include <stdio.h>
MainClass::MainClass(string _C) : _ClassName(_C)
{
}
MainClass::~MainClass()
{}
void MainClass::doSomething()
{
printf("Called from MainClass\n");
}
SubClass::SubClass(string className) : MainClass(className)
{
}
void SubClass::doSomething()
{
printf("Called from SubClass\n");
}
Call:
int main()
{
MainClass M1("test");
SubClass sub("SubClass");
MainClass *pointer = ⊂
M1.doSomething(); //Outputs 'Called from MainClass'.
sub.doSomething(); //Outputs 'Called from SubClass'.
pointer->doSomething(); //Also outputs 'Called from SubClass', since it points to sub and because sub overrides the behaviour from MainClass.
}
To call the parent method from the child method, you need to invoke the method from within the override with the parent class.
Example (in SubClass::doSomething): MainClass::doSomething().

Inheritance between two classes in c++ using the same data members and functions

I'm new to C++ programming and I want to create two classes that have the exact same data members and functions. Is it possible to create two inherited classes that have the same data members/functions instead of making several duplicate methods for each class. I'm making a c++ game based on zork and I want to create two items, weapons and fruits. Both will take in a name as a string and a value as a double. Do I create the header file as below:
#ifndef ITEM_H_
#define ITEM_H_
#include <map>
#include <string>
#include <iostream>
using namespace std;
class Item {
private:
string description;
string longDescription;
float value;
public:
Item (string description, float inValue);
Item (string description);
string getShortDescription();
string getLongDescription();
float getValue();
void setValue(float value);
};
class Weapon:: public Item{
};
class Fruit:: public Item {
};
#endif /*ITEM_H_*/
How would I no go about creating the methods without duplicating them?
Do nothing for now. Both Weapon and Fruit are Items and contain all the members and methods that Item does.
Sooner or later, you'll want to specialize behaviour of child classes and the implementation of the method in the base class won't do it (if it's sensible to have an implementation in the first place). This is where polymorphism comes in. You'll make the method in the base class virtual and override it in the derived class:
class Item {
public:
virtual void Use() = 0; // pure virtual method
};
class Weapon : public Item {
public:
virtual void Use() override
{
Fire();
}
private:
void Fire() { /* do something */ }
};
Now when you have a reference or a pointer to the base class and you call Use on it, it'll dispatch to the corresponding method in the derived class.
EDIT: There's no way around "duplicating" constructors. Each class needs at least one if it is ever to be instantiated. Since you declared Item (string description, float inValue); you need to define it as a member of Item, too:
Item (string description, float inValue)
: description(description) // <-- avoid duplicating names of members in parameter list,
, value(inValue) // it does the right thing, but hurts readability
{ /* body empty */ }
If you need to call the constructor of the derived class with same parameters, you need to define another constructor and forward the arguments to the constructor of base class:
Weapon::Weapon(string desc, float val)
: Item(desc, val) { }
In C++11, there's a shortcut - you can inherit constructors and the compiler will generate these forwarding constructors for you:
class Weapon : public Item {
using Item::Item;
};
There's (unfortunately, perhaps) no way to specify which constructors you want to inherit. It's all or nothing.
Hope that helps.
you need to call constructor of parent class to assign value to description; and longDescription; like
class Weapon:: public Item{
Weapon(string description, float inValue):Item(description,inValue){}
Weapon(string description):Item(description){}
};

Inheritance Beginner C++ Issue [duplicate]

This question already has answers here:
no default constructor exists for class x (inheritance) C++
(2 answers)
Closed 8 years ago.
I seem to be having a problem with Inheritance. Whenever I try to override a function in my Character.cpp file I get an error stating:'No default constructor exists for class Character'. I'm fairly new to c++ and I don't get why the error was appearing. What I want to do is basically override the GetFierceAttack() of the default Character class to be stronger for the child class which is called Ogre. I was wondering if I was using 'virtual' correctly.
My Character.h file
#ifndef CHARACTER_H
#define CHARACTER_H
#include <time.h>
#include <cstdlib>
class Character
{
protected:
int Health, LightAttack, FierceAttack, Damage;
public:
Character(int health, int lAttack, int fAttack, int damage);
~Character();
public:
int GetHealth() {return Health;}
int GetLightAttack() {return (rand()%5)+10;}
virtual int GetFierceAttack() {return (rand()%5)+10;}
void DeductDamage(int Damage);
};
//Overrides Fierce Attack
class Ogre:public Character
{
public:
Ogre(int health, int lAttack, int fAttack, int damage);
int GetFierceAttack() {return (rand()%10)+20;}
};
#endif
My Chacter.cpp file
#include "Character.h"
//Constructor
Character::Character(int health, int lAttack, int fAttack, int damage)
{
Health = health;
LightAttack = lAttack;
FierceAttack = fAttack;
Damage;
}
//Destructor
Character::~Character()
{
}
void Character::DeductDamage(int Damage)
{
Health -= Damage;
if(Health < 0)
{
Health = 0;
}
}
//Constructor
Ogre::Ogre(int health, int lAttack, int fAttack, int damage) //Here's the error
{
}
//Destructor
Ogre::~Ogre()
{
}
When you define constructor for class by yourself, you are overriding the default implementation.
So you need to provide default constructor as
class Character
{
public:
Character(){}
//----------your code-----//
}
Similarly for your destructor problem you first decalre destructor in class and then define it in .cpp file.
class Ogre:public Character
{
public:
~Ogre();
}
When you declare a non-default constructor for a class, the compiler does not generate a default constructor anymore.
So you have to provide your own.
When you call the constructor on a derived class, what happens is this:
the base object gets constructed first
any variables in the initialisation list get initialised
the body of the (derived) constructor is executed
If you do not specify a different constructor, the default constructor will be used for (1). You are getting a compiler error because you have no default constructor.
To specify a different constructor, do something like this:
Ogre::Ogre(int health, int lAttack, int fAttack, int damage) : Character (health, lAttack, fAttack, damage)
{
// body of constructor
}
Then the instance of the constructor that matches those parameters will be called instead. Since you have defined that, you won't get an error.
As for the error on the destructors, firstly, as others have said, you can't override the destructor without declaring it in the class. So you could add ~Ogre() to your class definition. However, you're not currently doing anything in your destructor body, so why are you redefining it at all? Just leave it as the default destructor.

Array of base abstract class containing children class in C++

so I have a Top class, let say:
//Top.h
#pragma once
#include <string>
using std::string;
class Top
{
protected:
string name;
public:
virtual string GetName() = 0;
}
This class won't have any object Top instantiate, that's why it's an abstract class. I also have two Middle class, let say:
//MiddleA.h
#pragma once
#include "Top.h"
class MiddleA : public Top
{
protected:
int value;
public:
MiddleA(string, int);
string GetName();
int GetValue();
}
//MiddleB.h
class MiddleB : public Top
{
protected:
double factorial;
public:
MiddleB(string, double);
string GetName();
double GetFactorial();
double Calculate(int);
}
Now, what I need is an array, or anything, that can contains multiple objects of type MiddleA, MiddleB or any classes that inherit from those two classes. Is there a way to do this in C++?
EDIT : Would it be "acceptable" to add a default constructor in the protected section and use a vector or array of Top?
Use the pointers and arrays of C++:
typedef std::array<std::unique_ptr<Top>,3> Tops;
Tops tops =
{{
new MiddleA( "Kuku", 1337 ),
new MiddleB( "Hoi", 42.0 ),
new MiddleC()
}};
Only thing you have to have virtual destructor on your Top. Without virtual destructor you may only use shared_ptr, others will result with undefined behavior when objects are destroyed.
yes. You could do it this way.
Top* array[3] = { new Top(parms), new MiddleA(params), new MiddleB(params) };
but you will be only able to call GetName() function. You wouldnt be able to call other methods.

Virtual deconstructors in interface->abstract->concrete class design

I have tried to answer this myself, by looking up several questions at StackOverflow. And although I think I understand this correctly, I can't fix this. Which, leaves me with the only obvious observation: I still don't get it.
I have made a summary of the questions at the bottom of this post, everything in between is information I have gathered and context for this question.
So, I get it that when you have a base class, and a derived class, your deconstructor should be marked virtual in the base class. To allow polymorphism.
But, I cannot seem to get my code to compile, or when it does compile, it does not link due 'undefined references'. I have been changing back and forth, but I never seem to get out of this cycle.
Basically I have an interace, defined like this:
#ifndef GUIELEMENT_H_
#define GUIELEMENT_H_
class GuiElement {
public:
virtual ~GuiElement();
virtual void draw() = 0;
};
#endif /* GUIELEMENT_H_ */
I have several objects extending from this. A simple relation is GuiWindow (directly derives from GuiElement):
#ifndef CGUIWINDOW_H_
#define CGUIWINDOW_H_
#include <assert.h>
#include <cstddef>
#include "../GuiElement.h"
#include "../GuiInteractionDelegate.h"
class GuiWindow : public GuiElement {
public:
GuiWindow(GuiInteractionDelegate * guiInteractionDelegate) {
assert(guiInteractionDelegate);
interactionDelegate = guiInteractionDelegate;
}
~GuiWindow() {
//delete interactionDelegate;
}
// called each frame, delegates its behavior to the given concrete cGuiWindowDelegate class.
void interact() {
interactionDelegate->interact(this);
}
private:
GuiInteractionDelegate * interactionDelegate;
};
#endif /* CGUIWINDOW_H_ */
This code does not link, gives me:
undefined reference to `GuiElement::~GuiElement()'
I thought it was sufficient to have an implementation in the GuiWindow class? Is that correct?
The next thing, which is really bugging me, is that I also have an abstract class derived from GuiElement, and concrete implementations on top of that. Basically giving:
GuiElement->GuiShape->GuiButton
Here is the header of GuiShape:
#ifndef GUISHAPE_H_
#define GUISHAPE_H_
#include "../GuiElement.h"
#include "../../gameobjects/Rectangle.h"
class GuiShape : public GuiElement {
public:
GuiShape(Rectangle * rect);
GuiShape(int x, int y, int width, int height);
~GuiShape();
void draw();
void setX(int value) { rectangle->setStartX(value); }
void setY(int value) { rectangle->setStartY(value); }
Rectangle * getRectangle() { return rectangle; }
bool isMouseOverShape();
void setColors(int darkBorder, int lightBorder, int inner);
int getDarkBorderColor() { return darkBorderColor; }
int getLightBorderColor() { return lightBorderColor; }
int getInnerColor() { return innerColor; }
protected:
Rectangle * rectangle;
private:
bool rectangleOwner;
int darkBorderColor;
int lightBorderColor;
int innerColor;
};
And finally GuiButton:
#ifndef CGUIBUTTON_H_
#define CGUIBUTTON_H_
#include <sstream>
#include <string>
#include "allegro.h"
#include "../../gameobjects/Rectangle.h"
#include "GuiShape.h"
class GuiButton : public GuiShape {
public:
GuiButton(Rectangle * rect, std::string theLabel);
GuiButton(int x, int y, int width, int height, std::string theLabel);
~GuiButton();
void draw();
std::string * getLabel() {
return label;
}
BITMAP * getBitmap() { return bitmap; }
void setBitmap(BITMAP * value) { bitmap = value; }
void setHasBorders(bool value) { hasBorders = value; }
void setPressed(bool value) { pressed = value; }
bool shouldDrawPressedWhenMouseHovers() { return drawPressedWhenMouseHovers; }
bool shouldDrawBorders() { return hasBorders; }
void setDrawPressedWhenMouseHovers(bool value) { drawPressedWhenMouseHovers = value; }
bool isPressed() { return pressed; }
private:
std::string * label;
bool drawPressedWhenMouseHovers;
bool hasBorders;
bool pressed;
BITMAP * bitmap;
void drawBackground();
void drawLighterBorder();
void drawDarkerBorder();
void drawButtonUnpressed();
void drawButtonPressed();
};
#endif /* CGUIBUTTON_H_ */
Which leads me to the following questions:
What is the best way to use virtual deconstructors where objects are derived from A->B->C ?
Should C only be the concrete virtual? And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)
Why would I get 'undefined references' with the straight-forward implementation of A->B ? (GuiElement->GuiWindow)
Thanks in advance for your help!
What is the best way to use virtual deconstructors where objects are derived from A->B->C ?
mark the base's (or all) destructor as virtual.
Should C only be the concrete virtual? And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)
Not sure what you mean by "concrete virtual" but a class with members that need destroying should destroy them in it's own destructor. No exceptions. when ~C is called, it destroys it's own stuff, and then ~B will be called automatically. The virtual just makes absolutely sure that ~C is called first.
Why would I get 'undefined references' with the straight-forward implementation of A->B ? (GuiElement->GuiWindow)
virtual ~GuiElement(); tells the compiler that the class has a destructor that will be defined later. You wanted either:
// There is no definition, cannot make a local "GuiElement" variable
// They can only make local "GuiButton" or other derived.
// You can still have pointers to a GuiElement.
// This is called "pure virtual"
virtual ~GuiElement() = 0;
or:
// There is a definition, someone can make a local "GuiElement" variable
virtual ~GuiElement() {};
I thought it was sufficient to have an implementation in the GuiWindow class? Is that correct?
No. A virtual function (that is not pure virtual, as your destructor of GuiElement) must be defined if it is declared in the class.
Destructors go even further: they must be implemented, always, even if it is pure virtual[1]. If you hadn't declared it, the compiler would create one (implicitly nonvirtual, but would be virtual if it would override a virtual destructor) for you. In C++11, you can just mark it "defaulted" (which means "compiler, implement that for me") and "deleted" which means "the program may never, implicitly or explicitly, destruct objects of this type".
What is the best way to use virtual deconstructors where objects are derived from A->B-
C ?
You usually want to make the topmost base's destructor virtual, that means all destructors in the hierarchy are virtual.
And if so, how do you release resources defined and handled only in B? (A=GuiElement, B=GuiShape, C=GuiButton)
In ~B(), naturally.
[1] :
12.4/7: A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any
derived class are created in the program, the destructor shall be defined. If a class has a base class with a
virtual destructor, its destructor (whether user- or implicitly- declared) is virtual.