I am new at programming using c++ and having some troubles creating my constructors & objects.
How can I access to my protected members like int p_iID in the Fahrzeug class?
I have to access them for both of my objects seperately.
I would be so happy if you could help me out with this.
class Fahrzeug {
private:
protected:
string p_sName;
int p_iID;
double p_dMaxGeschwindigkeit;
double p_dGesamtStrecke;
double p_dGesamtZeit;
double p_dZeit;
public:
virtual void vAusgeben(Fahrzeug* pFahrzeug1,Fahrzeug* pFahrzeug2);
virtual void vKopf();
virtual void vSimulieren(Fahrzeug *pFahrzeug, Fahrzeug *pFahrzeug2);
class PKW;
class PKW: public Fahrzeug{
PKW(const int p_iMaxID, string p_sName, double p_dMaxGeschwindigkeit, double p_dGesamtStrecke) {
p_iID = p_iMaxID;
this->p_sName = p_sName;
this->p_dMaxGeschwindigkeit = (p_dMaxGeschwindigkeit < 0) ? 0 : p_dMaxGeschwindigkeit;
this->p_dGesamtStrecke = p_dGesamtStrecke;
}
void vAusgeben(PKW pkw1, PKW pkw2) {
cout << "\n";
PKW pkw1;
PKW pkw2;
pkw1.vKopf();
cout << setw(5) << left << pkw1.p_iID<< " " << setw(10) <<pkw1.p_sName << setw(8) << " " << setw(15) << showpoint << pkw1.p_dMaxGeschwindigkeit << setw(3) << " " << pkw1.p_dGesamtStrecke; //Here I have the issue with pkw1.p_sName
cout << "\n";
cout << setw(5) << left << pkw2.p_iID << " " << setw(10) << pkw2.p_sName << setw(8) << " " << setw(15) << showpoint << pkw2.p_dMaxGeschwindigkeit << setw(3) << " " << pkw2.p_dGesamtStrecke;
cout << "\n";
}
}
void vAusgeben(PKW pkw1, PKW pkw2) {
You probably don't want to pass your PKW objects by value (or expect object slicing). Pass const references instead:
void vAusgeben(const PKW& pkw1, const PKW& pkw2) {
Also, why are you shadowing your 2 parameters with these local variables?
PKW pkw1; // ???
PKW pkw2; // ???
Aside from the issues raised in comments (and in another answer), there's a special rule for protected members that sometimes surprises people. An object of a derived type can access protected members of its base sub-object, but it can't access protected members of some other object. So:
struct B {
protected:
int i;
};
struct D : B {
void f(const B&);
};
void D::f(const B& b) {
i = 3; // okay, accessing my own protected member
b.i = 3; // no, access to protected member of different object not allowed
}
In the code in the question, the function PKW::vAusgeben can access its own copies of p_sName, p_dMaxGeschwindigkeit, and p_dGesamtStrecke, but it can't access pkw1.p_sName, pkw1.p_dMaxGeschwindigkeit, or pkw1.p_dGesamtStrecke.
Related
I'm still learning C++ so go easy on me.
Is there a way I can pass an object to a method without specifying an object? I'm probably butchering the terms so ill show code.
class Student
{private:
std::string Name;
float GPA;
char Sex;
int Absentee;
int *Data ;
public:
std::string GetName();
float GetGPA();
char GetSex();
int GetAbsentee();
void SetData(int);
int GetData();
int *GetDataAddr();
//Methods
void DisplayStudent(Student);
void Student::DisplayStudent(Student Stud)
{
std::cout << "___________________________________" << std::endl;
std::cout << "Name :" << Stud.GetName() << std::endl;
std::cout << "GPA :" << Stud.GetGPA() << std::endl;
std::cout << "Sex :" << Stud.GetSex() << std::endl;
std::cout << "Absentee :" << Stud.GetAbsentee() << std::endl;
std::cout << "Data :" << Stud.GetData() << std::endl;
std::cout << "Data Add :" << Stud.GetDataAddr() << std::endl;
std::cout << "___________________________________" << std::endl;
}
int main() {
Student Spike("Spike", 3.9f, 'M', 43,55);
* Compiles fine: Spike.DisplayStudent(Spike);
* DOSNT Compile: Student DisplayStudent(Spike);
* C++ a nonstatic member reference must be relative to a specific object*
return 0;
}
So the question I have is at least with this method, why do I need to specify or rather, what is the purpose of "Spike" in "Spike.DisplayStudent(.....)"? Student::Display(.....) makes far more sense to me.
If your Student::DisplayStudent is designed to display information for the student who is represented by that class instance, you don't need to pass Student Stud at all, just use member variables.
If however it is designed to display info for ANY student - you can make it a static member, or a free-standing function.
If you want the member function DisplayStudent to display the information for the very instance of Student on which the function is called, you do not need to pass a Student as an argument.
class Student {
public:
// The getter methods should be `const`, since calling them does not change
// the `Student`:
const std::string& GetName() const; // return a `const&` to avoid unecessary copying
void DisplayStudent() const; // No `Student` argument, like in `GetName()`
// ...
};
void Student::DisplayStudent() const {
std::cout << "___________________________________\n"
"Name :" << GetName() << "\n"
"GPA :" << GetGPA() << "\n"
"Sex :" << GetSex() << "\n"
"Absentee :" << GetAbsentee() << "\n"
"Data :" << GetData() << "\n"
"Data Add :" << GetDataAddr() << "\n"
"___________________________________\n";
}
You also do not need to call getter methods in DisplayStudent() since you have access to the private member variables and do not need to do any calculations before returning the result.
Usage example (if the appropriate constructor exists as you've indicated):
int main() {
Student Spike("Spike", 3.9f, 'M', 43,55);
Spike.DisplayStudent(); // no instance passed as an argument
}
First off: I know that it is generally a bad idea to change an object's class, but I'm implementing my own programming language, and it has variables that can contain values of any type, and even change their type at will, so please assume I'm not a beginner not understanding OO basics.
Currently, I implement my variant variables in C. Each one has a pointer to a table of function pointers, containing functions like SetAsInt(), SetAsString() etc., followed by what would be instance variables in C++. All objects are the same size.
When a variable contains a string and someone assigns an Int to it, I manually call the destructor, change the table of function pointers to point to the table used for variadic int values, and then set its int instance variable.
This is a bit hard to maintain, as every time I add a new type, I have to add a new table of function pointers and fill out all the function pointers in it. Structs of function pointers seem to be very badly type-checked, and missing fields don't lead to complaints, so I can easily accidentally forget one pointer in the list and get interesting crashes. Also, I have to repeat all the function pointers that are the same in most types.
I'd like to implement my variadic types in C++ instead, where a lot of this type-checking and inheriting default behaviours is done for me by the compiler. Is there a safe way to do this?
PS - I know I could create a wrapper object and use new to allocate a new object, but I can't have the additional extra allocation overhead for every int variable on the stack.
PPS - The code needs to be portable across Linux, Mac, iOS and Windows for now, but if someone has a standard C++ solution, that would be even better.
PPPS - The list of types is extensible, but predetermined at compile-time. The base layer of my language defines just the basic types, but the host application my language is compiled into adds a few more types.
Usage Example:
CppVariant someNum(42); // Creates it as CppVariantInt.
cout << "Original int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsInt(700); // This is just a setter call.
cout << "Changed int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsDouble(12.34); // This calls destructor on CppVariantInt and constructor on CppVariantDouble(12.34).
cout << "Converted to Double: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl; // GetAsInt() on a CppVariantDouble() rounds, or whatever.
(Imagine that beyond double and int, there would be other types in the future, like strings or booleans, but the caller of GetAsInt()/SetAsInt() shouldn't have to know what it is stored as, as long as it can be converted at runtime)
Here is a solution based on type-erasure, union and template specializations.
I'm not sure it fits your requirements.
Anyway, here is what it gets:
Anything is placed on the dynamic storage
No hierarchy required
You can easily improve it further to reduce the amount of code, but this aims to serve as a base point from which to start.
It follows a minimal, working example based on the intended use in the question:
#include<iostream>
class CppVariant {
union var {
var(): i{0} {}
int i;
double d;
};
using AsIntF = int(*)(var);
using AsDoubleF = double(*)(var);
template<typename From, typename To>
static To protoAs(var);
public:
CppVariant(int);
CppVariant(double);
int getAsInt();
double getAsDouble();
void setAsInt(int);
void setAsDouble(double);
private:
var data;
AsIntF asInt;
AsDoubleF asDouble;
};
template<>
int CppVariant::protoAs<int, int>(var data) {
return data.i;
}
template<>
int CppVariant::protoAs<double, int>(var data) {
return int(data.d);
}
template<>
double CppVariant::protoAs<int, double>(var data) {
return double(data.i);
}
template<>
double CppVariant::protoAs<double, double>(var data) {
return data.d;
}
CppVariant::CppVariant(int i)
: data{},
asInt{&protoAs<int, int>},
asDouble{&protoAs<int, double>}
{ data.i = i; }
CppVariant::CppVariant(double d)
: data{},
asInt{&protoAs<double, int>},
asDouble{&protoAs<double, double>}
{ data.d = d; }
int CppVariant::getAsInt() { return asInt(data); }
double CppVariant::getAsDouble() { return asDouble(data); }
void CppVariant::setAsInt(int i) {
data.i = i;
asInt = &protoAs<int, int>;
asDouble = &protoAs<int, double>;
}
void CppVariant::setAsDouble(double d) {
data.d = d;
asInt = &protoAs<double, int>;
asDouble = &protoAs<double, double>;
}
int main() {
CppVariant someNum(42);
std::cout << "Original int: " << someNum.getAsInt() << " (" << someNum.getAsDouble() << ")" << std::endl;
someNum.setAsInt(700);
std::cout << "Changed int: " << someNum.getAsInt() << " (" << someNum.getAsDouble() << ")" << std::endl;
someNum.setAsDouble(12.34);
std::cout << "Converted to Double: " << someNum.getAsInt() << " (" << someNum.getAsDouble() << ")" << std::endl;
}
On a lark, I tried using placement new to do this, and I have ... something ... It compiles, it does the job, but I'm not sure if it's an improvement over pure C. Since I can't have a union of C++ objects, I create a CPPVMAX() macro to pass the largest sizeof() of all subclasses as the size to mBuf[], but that's not really pretty either.
#include <iostream>
#include <string>
#include <cmath>
#define CPPVMAX2(a,b) (((a) > (b)) ? (a) : (b))
#define CPPVMAX3(a,b,c) CPPVMAX2((a),CPPVMAX2((b),(c)))
using namespace std;
class CppVariantBase
{
public:
CppVariantBase() { cout << "CppVariantBase constructor." << endl; }
virtual ~CppVariantBase() { cout << "CppVariantBase destructor." << endl; }
virtual int GetAsInt() = 0;
virtual double GetAsDouble() = 0;
virtual void SetAsInt( int n );
virtual void SetAsDouble( double n );
};
class CppVariantInt : public CppVariantBase
{
public:
CppVariantInt( int n = 0 ) : mInt(n)
{
cout << "CppVariantInt constructor." << endl;
}
~CppVariantInt() { cout << "CppVariantInt destructor." << endl; }
virtual int GetAsInt() { return mInt; }
virtual double GetAsDouble() { return mInt; }
virtual void SetAsInt( int n ) { mInt = n; }
protected:
int mInt;
};
class CppVariantDouble : public CppVariantBase
{
public:
CppVariantDouble( double n = 0 ) : mDouble(n)
{
cout << "CppVariantDouble constructor." << endl;
}
~CppVariantDouble()
{
cout << "CppVariantDouble destructor." << endl;
}
virtual int GetAsInt()
{
if( int(mDouble) == mDouble )
return mDouble;
else
return round(mDouble);
}
virtual double GetAsDouble() { return mDouble; }
virtual void SetAsDouble( int n ) { mDouble = n; }
protected:
double mDouble;
};
class CppVariant
{
public:
CppVariant( int n = 0 ) { new (mBuf) CppVariantInt(n); }
~CppVariant() { ((CppVariantBase*)mBuf)->~CppVariantBase(); }
operator CppVariantBase* () { return (CppVariantBase*)mBuf; }
CppVariantBase* operator -> () { return (CppVariantBase*)mBuf; }
protected:
uint8_t mBuf[CPPVMAX3(sizeof(CppVariantBase),sizeof(CppVariantInt),sizeof(CppVariantDouble))];
};
void CppVariantBase::SetAsInt( int n )
{
this->~CppVariantBase();
new (this) CppVariantInt(n);
}
void CppVariantBase::SetAsDouble( double n )
{
this->~CppVariantBase();
new (this) CppVariantDouble(n);
}
int main(int argc, const char * argv[]) {
CppVariant someNum(42);
cout << "Original int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsInt(700); // This is just a setter call.
cout << "Changed int: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
someNum->SetAsDouble(12.34); // This changes the class to CppVariantDouble.
cout << "Converted to Double: " << someNum->GetAsInt()
<< " (" << someNum->GetAsDouble() << ")" << endl;
return 0;
}
I have 3 classes (Cat, HouseCat:Cat, Lion:Cat).
What I'm trying to do is change HouseCat's VTable to make HouseCat eat Meat instead of cat food.
Classes I Use:
class Cat
{
public:
int age = 2;
virtual void eat() {
cout << "Meat" << this->age << endl;
};
virtual void sound() {
cout << "Meow!" << this->age << endl;
};
};
class HouseCat : public Cat
{
public:
virtual void eat() {
cout << "Cat Food" << this->age << endl;
};
};
class Lion : public Cat
{
public:
virtual void sound() {
cout << "ROAR!" << this->age << endl;
};
};
I'm trying to edit those classes' VTable entries by a VTable struct I created.
static void __memcpy(void * set, void * data, int size){
DWORD old;
VirtualProtect(set, size, PAGE_EXECUTE_READWRITE, &old);
char*dest = (char*)set;
char*src = (char*)data;
for (int i = 0; i < size; i++)dest[i] = src[i];
VirtualProtect(set, size, old, &old);
}
struct VTable{
static VTable read(void * object){
VTable vt = *(VTable*)(object);
int i = 0;
while ((DWORD)vt.functions[i] != 0x0)
i++;
vt.size = i;
return vt;
}
void ** functions;
int size;
void redirectFunction(int i, void * redirect){
__memcpy(&functions[i], &redirect, 4);
}
};
I confirmed that VTable[0] = eat(), so i decided to try making a change on the Vtable like this :
int main(int argc, char* argv[])
{
Lion lion = Lion();
Cat base = Cat();
HouseCat home = HouseCat();
VTable lionVTable = VTable::read(&lion);
VTable baseVTable = VTable::read(&base);
VTable homeVTable = VTable::read(&home);
cout << "-------------- BEFORE EDIT -----------------" << endl
<< "Base:" << endl
<< (baseVTable.functions[0]) << endl
<< (baseVTable.functions[1]) << endl
<< "HomeCat:" << endl
<< (homeVTable.functions[0]) << endl
<< (homeVTable.functions[1]) << endl
<< "Lion:" << endl
<< (lionVTable.functions[0]) << endl
<< (lionVTable.functions[1]) << endl;
homeVTable.redirectFunction(0, lionVTable.functions[0]);
cout << "-------------- AFTER EDIT -----------------" << endl
<< "Base:" << endl
<< (baseVTable.functions[0]) << endl
<< (baseVTable.functions[1]) << endl
<< "HomeCat:" << endl
<< (homeVTable.functions[0]) << endl
<< (homeVTable.functions[1]) << endl
<< "Lion:" << endl
<< (lionVTable.functions[0]) << endl
<< (lionVTable.functions[1]) << endl;
pause();
cout << "---Base---" << endl << endl;
base.eat();
base.sound();
cout << "---Lion---" << endl << endl;
lion.eat();
lion.sound();
cout << "---Home---" << endl << endl;
home.eat();
home.sound();
cout << "---End---" << endl;
pause();
return 0;
}
It outputed;
-------------- BEFORE EDIT ----------------
Base:
0031106E
0031121C
HomeCat:
00311285
0031121C
Lion:
0031106E
003113F2
-------------- AFTER EDIT -----------------
Base:
0031106E
0031121C
HomeCat:
0031106E
0031121C
Lion:
0031106E
003113F2
You can see that HomeCat[0] changed from 0x311285->0x31106E
VMT.exe+11285 - E9 B6350000 - jmp VirtualMethodTable test.HouseCat::eat
[Cat Food]
->
VMT.exe+1106E - E9 ED450000 - jmp VirtualMethodTable test.Cat::eat
[Meat]
The problem is the output of the functions didnt change at all.
---Base---
Meat2
Meow!2
---Lion---
Meat2
ROAR!2
---Home---
Cat Food2
Meow!2
---End---
I'm using Visual Studio 2013. Release/Debug didnt make a difference either.
Did i do something wrong in my code or is it somekind of compiler stuff I'm missing?
I agree that this is a horrible hacky thing to do... however, to get it working I'd try changing your lion/base/home variables to be pointers to objects. Right now since they are not pointers, the compiler may be automatically calling the correct function without using the vtable (since it knows exactly what type the object is).
I have a class A:
class Sportist{
private:
string ime;
int godina_na_ragjanje;
int godisna_zarabotuvacka_EUR;
public:
Sportist(string i, int g_n_r, int g_z_EUR){
ime = i;
godina_na_ragjanje = g_n_r;
godisna_zarabotuvacka_EUR = g_z_EUR;
}
string getIme(){
return ime;
}
int getGodinaNaRagjanje(){
return godina_na_ragjanje;
}
int getGodisnaZarabotuvackaEUR(){
return godisna_zarabotuvacka_EUR;
}
};
And class B using the class A as public:
class Fudbaler:public Sportist{
private:
int broj_na_odigrani_natprevari;
int danocna_stapka;
public:
Fudbaler(string ime, int godina, int zarabotuvacka, int b, int d)
:Sportist(ime, godina, zarabotuvacka)
{
broj_na_odigrani_natprevari = b;
danocna_stapka = d;
}
float danok(){
return getGodisnaZarabotuvackaEUR() * danocna_stapka;
}
friend ostream& operator<<(ostream &os, Fudbaler F){
return os << "Ime: " << getIme() << endl
<< "Godina na raganje: " << getGodinaNaRagjanje() << endl
<< "Godisna zarabotuvacka(EUR): " << getGodisnaZarabotuvackaEUR() << endl
<< "Danok sto treba da plati: " << danok();
}
};
And I get 4 errors as described in title in these lines:
return os << "Ime: " << getIme() << endl
<< "Godina na raganje: " << getGodinaNaRagjanje() << endl
<< "Godisna zarabotuvacka(EUR): " << getGodisnaZarabotuvackaEUR() << endl
<< "Danok sto treba da plati: " << danok();
cannot call member function 'std::string Sportist::getIme()' without object
cannot call member function 'int Sportist::getGodinaNaRagjanje()' without object
cannot call member function 'int Sportist::getGodisnaZarabotuvackaEUR()' without object
cannot call member function 'float Fudbaler::danok()' without object
i would say the function should be changed to
friend ostream& operator<<(ostream &os, Fudbaler F){
return os << "Ime: " << F.getIme() << endl
<< "Godina na raganje: " << F.getGodinaNaRagjanje() << endl
<< "Godisna zarabotuvacka(EUR): " << F.getGodisnaZarabotuvackaEUR() << endl
<< "Danok sto treba da plati: " << F.danok();
}
I am not shure about operator overloading for the std::streams. i usually have done that outside of the class. From your error messages, you need to use the passed Fudbaler variable to access the methods of it.
Long story short: The program I'm working on is a rogue like - even though that isn't really needed for this question.
Here's the hierarchy tree for my classes related to this question:
Entity
Item Creature
Weapon Armor
I have several virtual functions declared in Entity, which are also virtual in the classes derived from it.
I'm not sure how to word my question, but I'll explain the problem and post the code below. I have a factory type class, called ItemFactory, that opens an xml file and uses a simple parser that I made - and creates Item objects and sets their values. It has a method that returns an Item pointer. In my main file, I declare/define an ItemFactory object. When an Item needs to be dropped in the game, I use a pointer, that is of type, Item,
and call the method to randomly choose an Item to point to. All of this works perfectly..
Here's the problem. Entity has a virtual method called dumpObject() which prints the state of the variables it has. dumpObject() is also virtual in Item. When it's called from an Item, the method first calls Entity's dump with this:
Entity::dumpObject();
Then it dumps it's own variables.. I do the same for Weapon and Armor except using this:
Item::dumpObject();
My Question:
Since the ItemFactory holds both - Weapons and Armor, and the pointer in the main program points to an Item, shouldn't calling "itemPointer->dumpObject();" dump the values for Weapon/Armor (depending which it is pointing to..) which would also dump the values in Item which would also dump the values in Entity?
When I run the code, the only part that gets dumped is the part in Item and Entity.
Let me know if I need to provide more detail. Any suggestions? Thanks!
Here's the Code Snippets
I have the headers included, just tried to minimize the amount of code that I'm posting
Item.cpp
void Item::dumpObject(){
cout << "Item:" << endl;
dumpObjectData();
}
void Item::dumpObjectData(){
Entity::dumpObjectData();
cout << " [Weight] " << getWeight() << endl;
cout << " [Value] " << getValue() << endl;
cout << " [Quantity] " << getQuantity() << endl;
cout << " [Enchantment] " << getEnchantment() << endl;
}
Entity.cpp
void Entity::dumpObject(){
cout << "Entity:" << endl;
dumpObjectData();
}
void Entity::dumpObjectData(){
XMLSerializable::dumpObjectData(); //XMLSerialization handles parsing
cout << " [Name] " << getName() << endl;
cout << " [DisplayChar] " << getDisplayChar() << endl;
cout << " [Properties] " << endl;
for( auto it = m_vProperties.begin(); it != m_vProperties.end();it++ ){
cout << " - " << (*it) << endl;
}
}
Weapon.cpp
void Weapon::dumpObject(){
cout << "Weapon:" << endl;
dumpObjectData();
}
void Weapon::dumpObjectData(){
Item::dumpObjectData();
cout << " [Damage] " << getDamage() << endl;
cout << " [Range] " << getRange() << endl;
cout << " [Accuracy] " << getAccuracy() << endl;
cout << " [AmmoType] " << getAmmoType() << endl;
cout << " [Type] " << getType() << endl;
}
Armor.cpp
void Armor::dumpObject(){
cout << "Armor:" << endl;
dumpObjectData();
}
void Armor::dumpObjectData(){
cout << "calls to dump item data"<<endl;
Item::dumpObjectData();
cout << "calls to dump armor"<<endl;
cout << " [Type] " << getType() << endl;
cout << " [Slot] " << getSlot() << endl;
cout << " [ArmorValue] " << getArmorValue() << endl;
}
Main
ItemFactory myItems = ItemFactory::instance();
Item * pItem1 = myItems.generateItem();
pItem1->dumpObject();
Headers
Entity.h
#include "XMLSerializable.h"
#include <vector>
class Entity : public XMLSerializable {
public:
Entity(void);
virtual ~Entity(void);
virtual void dumpObject();
virtual void dumpObjectData();
};
Item.h
#include "Entity.h"
class Item : public Entity{
public:
Item(void);
virtual ~Item(void);
virtual void dumpObject();
virtual void dumpObjectData();
};
Weapon.h
#include "Item.h"
class Weapon : public Item {
public:
Weapon(void);
virtual ~Weapon(void);
virtual void dumpObject();
virtual void dumpObjectData();
};
Armor.h
#include "Item.h"
class Armor : public Item {
public:
Armor(void);
virtual ~Armor(void);
virtual void dumpObject();
virtual void dumpObjectData();
};
ItemFactory.cpp
ItemFactory & ItemFactory::instance(){
static ItemFactory myObj;
return myObj;
}
ItemFactory::ItemFactory(){
m_mtRandom.seed( time(NULL) );
fstream xmlFile;
xmlFile.open("items.xml");
vector<XMLSerializable*> pObjects;
parseXML(xmlFile, pObjects);
XMLSerializable * pObject;
for(auto it = pObjects.begin(); it != pObjects.end(); it++){
pObject = (*it);
Item * pItem = dynamic_cast<Item*>(pObject);
if (pItem != NULL){
m_vItems.push_back(pItem);
}
}
}
ItemFactory::~ItemFactory(){
}
Item * ItemFactory::generateItem() {
vector<Item*> tempItems;
for(auto it = m_vItems.begin(); it != m_vItems.end(); it++){
tempItems.push_back((*it));
}
int randomItem = (m_mtRandom() % (m_vItems.size() - 1));
Item * pItem = tempItems.at(randomItem);
Item * pReturnValue = new Item(*pItem);
return pReturnValue;
}
Now that I just did all that work, I don't think any of the code except maybe Main was necessary.. Lol I'm guessing my logic for the pointer in Main is wrong?
Well here's your problem:
Item * pReturnValue = new Item(*pItem);
This is giving you a shallow copy so that you do not get an Armor or Weapon.
If you need to do a copy given only a base class instance, define a clone method in the base class.
It looks like you are trying to use the prototype pattern, so you do want to create new instances?
class Entity : public XMLSerializable {
public:
Entity(void);
virtual ~Entity(void);
virtual Entity* clone() const { return new Entity(*this);}
virtual void dumpObject();
virtual void dumpObjectData();
};
class Armor : public Item {
public:
Armor(void);
virtual ~Armor(void);
virtual Armor* clone() const { return new Armor (*this);}
virtual void dumpObject();
virtual void dumpObjectData();
};
Note the use of covariant return values for clone(). I.e. The return values do differ but as the method signature matches and the return values are derived from one another, the call is virtual.
You then can write:
Item * pReturnValue = pItem->clone();
See: Wikipedia for background on the Prototype pattern.