How to do I/O on a pointer to a base class? - c++

For example, I have a base class A and its derived classes B, C, and so on. I have data with a pointer pointing to A. It might be new B, new C, and so on. Any easy way to write and read the pointer to/from a stream? My question is on how to get to know the concrete type. An example to show what I mean.
struct A { int i; };
struct B : public A { char c; };
struct C : public A { float f; }
struct Data
{
unique_ptr<A> mA;
};
Data data;
User works on data and then write out to a file and read in from the file.

The answer is you don't, you use virtual functions.
#include <iostream>
struct A {
int i;
virtual void describe() {
std::cout << "A:" << i << std::endl;
}
};
struct B : public A {
char c;
virtual void describe() override {
// Assume a 'B' wants to also output the A stuff.
std::cout << "B:" << c << ":";
A::describe();
}
};
struct C : public B {
float f;
virtual void describe() override {
// Assume a 'C' wants to also output the B stuff and A stuff.
std::cout << "C:" << f << ":";
B::describe();
}
};
#include <vector>
int main() {
std::vector<A*> bar;
A a;
a.i = 10;
B b;
b.i = 22;
b.c = 'b';
C c;
c.i = 5;
c.c = 'X';
c.f = 123.456;
bar.push_back(&a);
bar.push_back(&b);
bar.push_back(&c);
for (size_t i = 0; i < bar.size(); ++i) {
bar[i]->describe();
}
}
http://ideone.com/12BEce

Related

C++ operator new returns unexpected value

I am working with conversion operators and I an error just popped out of nowhere. C class is derived from B and has no relation with class A, however, debugger shows that when doing C* val1 = new C val1 is showed as C* {A<B>}. It also produces an error because that A in the C* pointer has a size of an unreasonable size (it gives a different size each time it is executed so I just suppose it gets a number from another application).
#include <iostream>
#include <vector>
template<typename widget_type>
class A
{
public:
std::vector<widget_type*> value;
virtual ~A() {}
void Add(widget_type* val)
{
value.push_back(val);
}
template<typename return_type>
operator A<return_type>()
{
unsigned int size = this->value.size();
std::vector<return_type*> return_value;
return_value.reserve(size);
for (unsigned int i = 0; i < size; i++)
{
return_value[i] = dynamic_cast<return_type*>(this->value[i]);
}
A<return_type> target;
target.value = return_value;
return target;
}
};
class B
{
public:
virtual ~B() {}
};
class C : public B
{
public:
void Print()
{
std::cout << "C CALL\n";
}
};
class D : public B
{
};
int main()
{
std::cout << "Start!\n";
A<C> source;
C* val1 = new C;
source.Add(val1);
A<B> target = source;
A<B>* target2 = dynamic_cast<A<B>*>(&source);
std::cout << "END\n";
}```
for (unsigned int i = 0; i < size; i++)
{
return_value[i] = dynamic_cast<return_type*>(this->value[i]);
}
You are invoking undefined behaviour by accessing return_value[i] on an empty vector.

Is there a way to call derived class functions with base class pointer without virtual

I have an interesting problem to deal with. Is there any way to call derived class functions with base class pointer without virtual pointers? IMHO, I do not think so but would like to clear with experts.
Consider this example:
class B {
public:
int a;
int b;
int get_a() { return a };
int get_b() { return b };
B() : a(1), b(2) { }
};
class D : public B {
public:
int a;
int b;
int get_a() { return a };
int get_b() { return b };
D() : a(3), b(4) { }
};
int main() {
Base* b = new Base;
std::cout << b->get_a() << std::endl; // Gives 1
std::cout << b->get_b() << std::endl; // Gives 2
// Do something here which instantiates Derived and can call Derived functions using base class pointers.
// Maybe Base\* b = new Derived();
// But doing b->get_a() should call Derived class function get_a.
std::cout << <some_base_class_pointer_after_doing_something>->get_a() << std::endl; // Should give 3
std::cout << <some_base_class_pointer_after_doing_something>->get_b() << std::endl; // Should give 4
}
Is there any possible way? reinterpret_cast or anything else?
I do not want to use virtual since vptr comes into the picture and increases the memory by 8 bytes(depends) per object. Very frequently, I can have big number of B type objects. Say, 1 million objects of B type, I do not want my program memory to go by 1m x 8 bytes. Instead, I would rather not have virutal/vptr in such huge cases.
I would be happy to write more details if needed.
You can write:
Base* b = new Derived;
Derived *d = static_cast<Derived *>(b);
std::cout << d->get_b() << '\n';
Of course, this would cause undefined behaviour if you tried it on a b that did not actually point to a Derived or child class of such. If you are in general not sure what the pointer points to, and you don't want to use vtables, you'll need to manually implement something to give you that information (e.g. a member variable of Base with type information).
Since I could not get any answer from anyone, let me float an option here which I have thought of. This might be a hack though. I am open for correction/comments and criticism as well. :)
The deal is to do reinterpret_cast in the base class functions.
#include <iostream>
#include <vector>
bool preState = true;
class Derived;
class Base;
class Base {
public:
unsigned char a;
int b;
Base() : a('a'), b (2) { };
unsigned char get_a() const;
int get_b() const;
} __attribute__ ((__packed__)) ;
class __attribute__ ((__packed__)) Derived : public Base {
public:
unsigned char c;
int d;
Derived() : c('c'), d(4) { };
unsigned char get_a() const;
int get_b() const;
};
unsigned char Base::get_a() const {
if (preState) {
return a;
} else {
const Derived* d = reinterpret_cast<const Derived*>(this);
return d->get_a();
}
}
int Base::get_b() const {
if (preState) {
return b;
} else {
const Derived* d = reinterpret_cast<const Derived*>(this);
return d->get_b();
}
}
unsigned char Derived::get_a() const {
return c;
}
int Derived::get_b() const {
return d;
}
int main() {
std::vector<Base*> bArray;
bArray.push_back(new Base());
bArray.push_back(new Base());
std::vector<Base*>::iterator bArrayIt = bArray.begin();
for (; bArrayIt != bArray.end(); ++bArrayIt) {
std::cout << (*bArrayIt)->get_a() << " ";
std::cout << (*bArrayIt)->get_b() << std::endl;
}
preState = false;
std::vector<Base*> dArray;
bArrayIt = bArray.begin();
for (; bArrayIt != bArray.end(); ++bArrayIt) {
// Write copy constructor in Derived class which copies everything from
// base object to Derived object
Base* b = new Derived();
dArray.push_back(b);
}
std::vector<Base*>::iterator dArrayIt = dArray.begin();
for (; dArrayIt != dArray.end(); ++dArrayIt) {
std::cout << (*dArrayIt)->get_a() << " ";
std::cout << (*dArrayIt)->get_b() << std::endl;
}
}
The output of this would be:
a 2 // Base class get_a() and get_b()
a 2 // Base class get_a() and get_b()
c 4 // Derived class get_a() and get_b()
c 4 // Derived class get_a() and get_b()

Can i use C++ function pointers like a C#'s Action?

In C ++, I first encountered function pointers.
I tried to use this to make it similar to Action and Delegate in C #.
However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.
ex) void (A :: * F) ();
Can I use a function pointer that can store a member function of any class?
In general, function pointers are used as shown in the code below.
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(A::*BF)();
};
int main()
{
A a;
B b;
b.BF = &A::AF;
(a.*b.BF)();
return 0;
}
I want to use it like the code below.
is this possible?
Or is there something else to replace the function pointer?
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(* BF)();
};
int main()
{
A a;
B b;
b.BF = a.AF;
return 0;
}
I solved the question through the answer.
Thanks!
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class C {
public:
void CF() { std::cout << "C::F" << std::endl; }
};
class B {
public:
B(){}
std::function<void()> BF;
};
int main() {
A a;
C c;
B b;
b.BF = std::bind(&A::AF, &a);
b.BF();
b.BF = std::bind(&C::CF, &c);
b.BF();
int i;
std::cin >> i;
return 0;
}
What you want to do is probably something like this. You can use std::function to hold a pointer to a member function bound to a specific instance.
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class B {
public:
B(const std::function<void()>& bf) : BF(bf) {}
std::function<void()> BF;
};
int main() {
A a;
B b1(std::bind(&A::AF, &a)); // using std::bind
B b2([&a] { a.AF(); }); // using a lambda
b1.BF();
b2.BF();
return 0;
}
Here's a C# style implementation of the accepted answer, It is memory efficient and flexible as you can construct and delegate at different points of execution which a C# developer might expect to do:
#include <iostream>
#include <functional>
using namespace std;
class A {
public:
void AF() { cout << "A::F" << endl; }
void BF() { cout << "B::F" << endl; }
};
class B {
public:
std::function<void()> Delegate;
};
int main() {
A a;
B b;
b.Delegate = std::bind(&A::AF, &a);
b.Delegate();
b.Delegate = [&a] { a.BF(); };
b.Delegate();
return 0;
}

collect different types of class and call their methods in c++

Is there any way in C++ to collect different types of classes and call their methods?
What I want to do is as below,
template<namespace T>
class A
{
A method_A1(T a)
{
...
}
void method_A2(int aa)
{
...
}
...
};
class B
{
...
};
class C
{
...
};
class D
{
...
};
A<B> *b;
A<C> *c;
A<D> *d;
b -> method_A2(3);
c -> method_A2(5);
In this code object b,c,d they are totally different object, right? Not related.
But I want to bind them with a array, so...
z[0] = b;
z[1] = c;
z[2] = d;
like this.
I found some solutions, however the solutions are only for collecting different types. (using void* arrays or vectors for inherited objects) I also wanna access to their methods.
z[0] -> method_A2(3);
z[1] -> method_A3(5);
like this.
In this case how should I do?
Thanks in advance.
typedef boost::variant<A<B>, A<C>, A<D>> AVariant;
std::array<AVariant, 3> z;
z[0] = *b;
z[1] = *c;
z[2] = *d;
Then you can inspect each element's type if needed, or "visit" them using boost::static_visitor as shown here: http://www.boost.org/doc/libs/release/doc/html/variant.html
Why you don't use inheritance and polymorphisms. I have posted an example of what exactly can be a solution of your problem. See the main function:
#include <iostream>
class weapon {
public:
int fireRate;
int bulletDamage;
int range;
int activeBullet;
public:
virtual void fire(void) {std::cout << "machine " << '\n';}
virtual ~weapon() {std::cout << "destructor is virtual" << '\n';}
};
class machineGun: public weapon {
public:
void fire(void) {std::cout << "machine gun firing" << '\n';}
~machineGun(void) { std::cout << "machine gun destroyed" << '\n';}
};
class flamer: public weapon {
public:
void fire(void) {std::cout << "flamer firing" << '\n';}
~flamer(void) {std::cout << "flamer destroyed" << '\n';}
};
int main(void)
{
const int count = 2;
weapon *weapons[count];
machineGun *a = new machineGun();
flamer *b = new flamer();
weapons[0] = a;
weapons[1] = b;
weapons[0]->fire();
weapons[1]->fire();
delete a;
delete b;
}
If you don't want to change your classes' hierarchy, you can try having an array of callable objects. Something like:
#include <iostream>
#include <functional>
#include <array>
class A
{
public:
void Foo(int a)
{
std::cout << "Foo " << a << std::endl;
}
};
class B
{
public:
void Bar(int a)
{
std::cout << "Bar " << a << std::endl;
}
};
int main()
{
using namespace std::placeholders;
A a;
B b;
auto a_func = std::bind(&A::Foo, a, _1);
auto b_func = std::bind(&B::Bar, b, _1);
std::array<std::function<void(int)>, 2> arr = {
std::bind(&A::Foo, a, _1),
std::bind(&B::Bar, b, _1)
};
arr[0](1);
arr[1](2);
return 0;
}
BTW, this will only work if you use compiler with full C++11 support.

C++ operator overloading in abstract class

Let's say we have the following scenario:
We have a base abstract class A. Then we have classes B and C which derived from A. We also have class D which is a custom implementation of a std::vector<T> - it contains a private property list of type std::vector<T> and some custom methods to work with it.
Now my problem is as follows: I would like to overload the operator + in class A to be able to do this:
B* b = new B();
C* c = new C();
D mList = b+c; //the property *list* of mList would contain b an c
I have tried everything and can't seem to be able to get it to work and am out of ideas. Is it even possible to override an operator in a base abstract class so that it will apply to derived classes?
EDIT:
Here is what I have tried so far:
File A.h:
#pragma once
#include <string>
#include <iostream>
using namespace std;
class A
{
protected:
double price;
string name;
public:
A() :name(""){};
A(string n, double p){
price = p;
name = n;
};
~A(){};
virtual void calculate(double value) = 0;
virtual void print() const = 0;
};
File B.h:
#pragma once
#include "A.h"
class B : public A
{
private:
public:
B() :A(){};
B(string n, double p) :A(n,p){};
~B();
void calculate(double value)
{
price = price + value;
}
void print() const
{
cout << name << " says: " << " " << price;
}
};
File C.h:
#include "A.h"
class C : public A
{
private:
public:
C() :A(){};
C(string n, double p) : A(n,p){};
~C();
void calculate(double value)
{
price = price * value;
}
void print() const
{
cout << name << " says: " << " " << price;
}
};
File D.H:
#include <vector>
class D
{
private:
vector<A*> list;
public:
D(){}
~D()
{
int len = list.size();
for (int i = 0; i < len; i++)
{
delete list[i];
}
};
void push(A* item)
{
list.push_back(item);
}
A* pop()
{
A* last = list.back();
list.pop_back();
return last;
}
//I have tried overriding it here and in A.h
friend D D::operator+(A* first, A* second)
{
D temp;
temp.push(first);
temp.push(second);
return temp;
}
};
It looks like you're are adding two pointers, so A::operator+() won't even be called. But to answer your question, yes, operator overloading is inheritable. Even from an abstract base class.
class A
{
public:
virtual void test() = 0;
int operator+(const A &a) {return 42;}
};
class B : public A
{
void test() {};
};
class C : public A
{
void test() {};
};
int main()
{
B* b = new B();
C* c = new C();
cout << "result: " << *b + *c << endl;
return 0;
}
Output:
result: 42
When c in C* and d is a D* if you write c+d you're just adding pointers, whatever overloads you defined.
Maybe you could redefine pointer addition for A* with a global operator(A*, A*) (not sure it's possible) but it would be quite dangerous for users since it overrides standard behavior.
The better solution is to define operators on references (const) and not pointers, which in your case is a little less convenient since you'd have to write: list = *c + *d;
Also, since you're using containers of pointers for polymorphism, I strongly recommend using shared_ptr.
Working code below (simplified, but with the ability to add more than 2 elements):
#include <list>
using std::list;
struct A {
list<const A*> operator+(const A& right) { // A + A
list<const A*> r;
r.push_back(this);
r.push_back(&right);
return r;
}
list<const A*> operator+(const list<const A*> & right) { // A + list
list<const A*> r = right;
r.push_front(this);
return r;
}
virtual void print() const = 0;
};
list<const A*> operator+(const list<const A*> & left, const A & right) { // list + A
list<const A*> r = left;
r.push_back(&right);
return r;
}
#include <iostream>
struct B : A {
void print() const { std::cout << "B" << std::endl; }
};
struct C : A {
void print() const { std::cout << "C" << std::endl; }
};
int main() {
B b;
C c;
B* pb = new B;
list<const A*> lst = b + c + *pb;
for(list<const A*>::iterator i = lst.begin(); i != lst.end(); ++i) {
(*i)->print();
}
return 0;
}
Take a look at this code-example:
#include <iostream>
class B;
class A;
class A
{
public:
virtual void overrideProp() = 0;
friend int operator+(const B& b, const A& a);
friend std::ostream& operator<<(std::ostream& os, const A& a)
{
return os << a.prop;
}
protected:
int prop;
};
class B : public A
{
public:
B(){overrideProp();}
void overrideProp(){prop=1;}
};
class C : public A
{
public:
C(){overrideProp();}
void overrideProp(){prop=3;}
};
int operator+(const B& b, const A& a)
{
return b.prop + a.prop;
}
class D
{
public:
void operator=(const int& i){d = i;}
friend std::ostream& operator<<(std::ostream& os, const D& a)
{
return os << a.d;
}
private:
int d;
};
int main()
{
B b;
C c;
D d; d = b+c;
std::cout << "B contains: " << b << " C contains: " << c << " D contains: " << d;
}
The output is B contains: 1 C contains: 3 D contains: 4
Here's an compilable and runnable example (http://codepad.org/cQU2VHMp) I wrote before you clarified the question, maybe it helps. The idea is that the addition overload can either be unary (and D defined as a friend), as here, or defined as a non-member binary operator using public methods. Note that I have to dereference the pointers b and c to make this work, as adding pointers often don't make sense.
#include <iostream>
#include <string>
class D {
public:
void Foo() {
std::cout << "D: " << member_ << std::endl;
}
friend class A;
private:
std::string member_;
};
class A {
public:
virtual void Foo() = 0;
A(const std::string &member) : member_(member) {}
D operator+(const A &rhs) {
D out;
out.member_ = member_ + " " + rhs.member_;
return out; // Uses the default copy constructor of D
}
protected:
std::string member_;
};
class B : public A {
public:
B(const std::string &member) : A(member) {}
void Foo() {
std::cout << "B: " << member_ << std::endl;
}
};
class C : public A {
public:
C(const std::string &member) : A(member) {}
void Foo() {
std::cout << "C: " << member_ << std::endl;
}
};
int main() {
B *b = new B("hello");
C *c = new C("world");
b->Foo();
c->Foo();
D d = (*b) + (*c);
d.Foo();
delete b;
delete c;
return 0;
}
The output of this program is:
B: hello
C: world
D: hello world