cpp store the objects in an array of pointer - c++

I am trying to do something like this with c++.
void showContensofArray(void *data[])
{
//In this function have to display the values of respective objects.
// Any ideas how do I do it?
}
int main(){
A phew(xxx,abcdefg); //object of class A
B ball(90),ball2(88); //object of class B
void *dataArray[2];
dataArray[0] = &ph1;
dataArray[1] = &ball;
showContentsofArray(dataArray); //function
}

If you want to treat the objects in the data[] generically (i.e by calling a common function on them to extract a description or values) then define a class hirachy for your objects and in your showContentsofArray function call virtual methods on your (common base class) object pointers.
This is a textbook example of Polymorphism:
"polymorphism allows values of different data types to be handled using a uniform interface."
In the example below the base class BaseObject defines the uniform interface.
class BaseObject {
virtual string description() { return "Base object"; }
virtual bool bounces() { return false; }
}
class B : public BaseObject {
string description() { return "Im a B object" }
bool bounces() { return true; }
}
class A : public BaseObject {
string description() { return "Im an A object" }
}
void showContensofArray(BaseObject* data[], int size) {
for (int i=0; i<size; i++) {
cout << data[i]->description();
if (data[i]->bounces())
cout << "I bounce!";
}
}
int main() {
A phew(xxx,abcdefg); //object of class A
B ball(90),ball2(88); //object of class B
BaseObject* dataArray[2];
dataArray[0] = &ph1;
dataArray[1] = &ball;
showContentsofArray(dataArray);
}
Will output:
Im an A object
Im a B object
I bounce!

void showContensofArray(void *data[], int len)
{
int i;
for(i=0;i<len;i++){
((Base*)(data[i]))->print();
}
}
And every Class should have an implementation of the method print() that knows how to print its values.
You could also use inheritance.
EDIT:
#Ricibob's answer is correct, but if you need to do the casting inside the function, you need to do something like this:
#include <iostream>
using namespace std;
class Base{
public:
virtual void print()=0;
};
class A: public Base{
public:
void print(){
cout<<"Object A"<<endl;
}
};
class B: public Base{
public:
void print(){
cout<<"Object B"<<endl;
}
};
void showContensofArray(void* data[], int len)
{
int i;
for(i=0;i<len;i++){
((Base*)(data[i]))->print();
}
}
int main(){
A a;
B b;
void* v[2];
v[0]= &a;
v[1] = &b;
showContensofArray(v,2);
return 0;
}
You can't evade inheritance.

Just cast back to the original type:
A* p1 = static_cast<A*>(data[0]);
B* p2 = static_cast<B*>(data[1]);

Related

How to set the value of a variable of derived class by using the base class object?

I need to assign x = 2000 to x of B via object a of A
Here B is the derived class i.e inherits the class A.
class A
{
public:
int x, y;
void print()
{
cout<<endl<<"print() of A";
}
virtual void display()
{
cout<<endl<<"display() of A";
}
};
class B: public A
{
public:
int x, z;
void display()
{
cout<<endl<<"display() of B";
}
void print()
{
cout<<endl<<"print() of B";
}
};
Found the answer by doing the following:
((B *)aptr)->x = 2000;
In C++, polymorphism is implemented via virtual functions. If you need to change something in a derived class through a pointer or reference to its base type, you need a virtual function. (Well, technically, you don't; you could cast to the derived type, but that's an admission of design failure).
It can be done by creating virtual function in base class which effect to call function of derive class for initialization.
#include<iostream>
#include<stdio.h>
using namespace std;
class A
{
public:
int x, y;
void print()
{
cout<<endl<<"print() of A";
}
virtual void display()
{
cout<<endl<<"display() of A";
}
virtual void setX(int a)
{
}
};
class B: public A
{
public:
int x, z;
void display()
{
cout<<endl<<"display() of B";
}
void print()
{
cout<<endl<<"print() of B";
}
void setX(int a)
{
x=a;
}
};
int main()
{
A *ptr;
B b;
ptr=&b;
ptr->setX(2000); ///using pointer object of class A
cout<<b.x;
}
I think it will help you :)

Copied object changes attributes from the base class pointer it used to copy

Consider the following classes:
class Base {
public:
... // include virtual destructor and rest of methods
virtual void changeField(int val) = 0;
virtual Base * clone() const = 0;
};
class Derived: public Base {
int x;
public:
... // include its destructor and rest of its methods
void changeField(int val) { x = val; }
Derived * clone() const { return new Derived(*this); }
};
Suppose I have an existing Base * pointer bp that points to an Derived object. Then I call bp->clone() to make a copy and store the pointer of the resulting object in a Base * pointer, copyPointer.
When I try to changeField on the copyPointer, the value is changed, but the original object has its field also changed. Why is this? And what can I do to prevent this? Would I have to create an entirely new object from scratch?
Edit: Here is my main function in which I implement the described scenario
int main() {
try {
Base * copyPointer = bp->clone();
copyPointer->changeField(5);
cout << copyPointer->print() << endl; //prints the field of Derived
delete copyPointer;
}
catch (exception& e) { // I also have an Exception class in my code
cout << e.what() << endl;
}
}
Your assumption, that the function changeField() on the copyPointer changes the original object, is wrong!
I elaborated your example:
#include <iostream>
using std::cout;
using std::endl;
class Base {
public:
// include virtual destructor and rest of methods
virtual void changeField(int val) = 0;
virtual Base * clone() const = 0;
virtual int print() const =0;
};
class Derived: public Base {
int x;
public:
// include its destructor and rest of its methods
Derived(int i):x(i) {}
void changeField(int val) { x = val; }
Derived * clone() const { return new Derived(*this); }
int print()const { return x; }
};
int main() {
Base* bp =new Derived(3);
cout <<bp->print() <<endl;
Base * copyPointer = bp->clone();
copyPointer->changeField(5);
cout <<copyPointer->print() <<endl; //prints the field of Derived
cout <<bp->print() <<endl;
}
and the output is:
3
5
3

Accessibility of C++ vector in derived class from base class

My scenario is simplified in the following example:
#include <iostream>
#include <vector>
using namespace std;
class C;
class A
{
protected:
C * cPointer;
A();
virtual void updateList() = 0;
void callFunc();
};
class B : public A
{
private:
vector<int> list;
void updateList();
public:
void callFromA();
};
class C
{
friend class A;
friend class B; // I want to get rid off this declaration
private:
int sum;
void set_sum( int val );
public:
static C * getCPointer();
};
A::A()
{
cPointer = C::getCPointer();
}
void A::callFunc()
{
updateList();
}
void B::updateList()
{
list.push_back(2);
list.push_back(4);
int s = 0;
for( unsigned int i=0; i<list.size(); i++ )
{
s += list[i];
}
cPointer->set_sum(s);
}
void B::callFromA()
{
callFunc();
}
void C::set_sum( int val )
{
sum = val;
cout << "Sum at C is: " << sum << endl;
}
C * C::getCPointer()
{
static C cPointer;
return & cPointer;
}
int main( int argc, char ** argv)
{
B b;
b.callFromA();
return 0;
}
This example works fine. But I want to get rid of the "friend class B" declaration in class C and achieving similar functionality. Actually I want to have either of the following:
accessibility of C::set_sum() from B::updateList() which will not be possible without the "friend class B" declaration in class C.
accessibility of B::list in A::callFunc() whereby I can push the logic from B::updateList to A::callFunc() which basically means ability to access a list in the derived class from the base class. In this way, I will be able to access the set_sum() in A::callFunc() due to "friend class A" declaration in class C.
Any idea to achieve this without involving major design changes is desirable!
Thanks!
I'm not sure if I understand all your restrictions, but maybe this works better for you. Basically, you can access B::list from A using a virtual function. I've commented the changes in the code.
#include <iostream>
#include <vector>
using namespace std;
class A;
class C
{
friend class A;
private:
int sum;
void set_sum(int val);
public:
static C * getCPointer();
};
class A
{
protected:
C * cPointer;
A();
virtual int getS() = 0; // virtual function to calculate data from vector in derived class B
virtual void updateList()
{
cPointer->set_sum(getS()); // A is friend of C, so you can access B data from A
}
void callFunc();
};
class B : public A
{
private:
vector<int> list;
void updateList();
int getS() // concrete implementation to access vector data
{
int s = 0;
for (unsigned int i = 0; i < list.size(); i++)
{
s += list[i];
}
return s;
}
public:
void callFromA();
};
A::A()
{
cPointer = C::getCPointer();
}
void A::callFunc()
{
updateList();
}
void B::updateList()
{
list.push_back(2);
list.push_back(4);
A::updateList(); // Call to super implementation
}
void B::callFromA()
{
callFunc();
}
void C::set_sum(int val)
{
sum = val;
cout << "Sum at C is: " << sum << endl;
}
C * C::getCPointer()
{
static C cPointer;
return &cPointer;
}
int main(int argc, char ** argv)
{
B b;
b.callFromA();
return 0;
}
You can not access members of derived classes inside the base class, period. The object at hand might be of the base class, or even of a completely unrelated derived class, with guaranteed "interesting" consecuences. Any design asking for doing so is seriously broken, and needs rethinking.
You can make the member function of the base class which wants to do so virtual, and redefine it in the derived class to do whatever perversion you have in mind. Meanwhile, the chaste member of the base class can just refuse if called, signalling the mistake in a sane way. That way you get a guarantee that nothing too untoward can happen.

Calling a derived virtual function

I'm still fairly new to C++ and inheritance has gotten me in a pickle.
I know this works in C# since I'm always using Base.();
I'm hoping to be able to call a vector array of PlayerCharacter, derived from Entity.
Currently when I call it, it only calls Entity's update method.
int main()
{
vector<Entity*> list;
list.push_back(&PlayerCharacter());
for(int i = 0; i < list.size(); i++)
{
list[0]->Update();
}
}
class Entity
{
public:
Entity(void);
~Entity(void);
int hitpoints;
virtual void Update(void);
};
void Entity::Update(void)
{
int a = 0;
a++;
}
class PlayerCharacter : public Entity
{
public:
PlayerCharacter(void);
~PlayerCharacter(void);
bool Move();
void Update() override;
};
void PlayerCharacter::Update(void)
{
int a = 0;
a--;
}
list.push_back(&PlayerCharacter()); i think this is undefined behavior in your code.
In your case you should allocate the data on the heap like this: list.push_back( new PlayerCharacter() ); otherwise if you do this &PlayerCharacter() then the PlayerCharacter variable will be destroyed immediately and the pointer inside the list will point to garbage bytes.
Also to track which function is called you can use the debugger or print something in the console from each Update function.
This Works :
Few changes though : 1) You dont need to put Override 2) Definition of Constructor and destructor once declared 3) Created object of derived class and passed it to the list.
Output is : Inside PlayerCharacter
If you want to call base class update method method remove the volatile keyword. Or use base class pointer pointing to base class object.
class Entity
{
public:
Entity();
~Entity();
int hitpoints;
virtual void Update(void);
};
Entity::Entity()
{
}
Entity::~Entity()
{
}
void Entity::Update(void)
{
std::cout << " Inside Entity" <<std::endl;
int a = 0;
a++;
}
class PlayerCharacter : public Entity
{
public:
PlayerCharacter();
~PlayerCharacter();
bool Move();
void Update();
};
void PlayerCharacter::Update(void)
{
std::cout << " Inside PlayerCharacter" <<std::endl;
int a = 0;
a--;
}
PlayerCharacter::PlayerCharacter()
{
}
PlayerCharacter::~PlayerCharacter()
{
}
int main()
{
vector<Entity*> list;
PlayerCharacter ObjPlayerCharacter;
list.push_back(&ObjPlayerCharacter );
for(unsigned int i = 0; i < list.size(); i++)
{
list[0]->Update();
}
}

C++ inheritance, function not replaced in child-class

I have a problem with inheritance in C++. The attached code produces the output "1,1," but I thought the action methods from the classes b and c replace the action method from class a. So I expected the output "2,3,". What do I have to change to get the output "2,3,"?
#include <iostream>
//Class a
class a
{
public:
a();
int action();
};
a::a()
{
}
int a::action()
{
return 1;
}
//Class b
class b : public a
{
public:
b();
int action();
};
b::b()
{
}
int b::action()
{
return 2;
}
//Class c
class c : public a
{
public:
c();
int action();
};
c::c()
{
}
int c::action()
{
return 3;
}
//Main Programm
int main()
{
a arr[2];
arr[0] = b();
arr[1] = c();
for(int i = 0; i<2; i++)
{
std::cout << arr[0].action() << ",";
}
return 0;
}
Action needs to be virtual in the base class, otherwise you can't override it.
You can use the foo() override notation to get a compile-time check as to whether you're really overriding something.
You will have to access the derived type trough a pointer to the base type, otherwise you'll slice and do other nasty things. Also sometimes it's a good idea to also make your destructor virtual.
class Base { };
class Derived : public Base { };
some_container<Base*> baseOrDerived;
Then you can allocate both Base and Derived objects into this container. For example with new, although you probably want to use std::shared_ptr<Base> or std::unique_ptr<Base> instead of Base*.
you can use virtual function to get the output "2,3":
first, you should change void action(); to virtual void action(); in class a;
second, you should use pointer to implement polymorphism;
third, you should change arr[0] to arr[i];
Here is my code:
#include <iostream>
//Class a
class a
{
public:
a();
virtual int action();
};
a::a()
{
}
int a::action()
{
return 1;
}
//Class b
class b : public a
{
public:
b();
int action();
};
b::b()
{
}
int b::action()
{
return 2;
}
//Class c
class c : public a
{
public:
c();
int action();
};
c::c()
{
}
int c::action()
{
return 3;
}
int main(int argc, char *argv[])
{
a *(arr[2]);
arr[0] = new b();
arr[1] = new c();
for(int i = 0; i<2; i++)
{
std::cout << arr[i]->action() << ",";
}
return 0;
}
Here is my output: