C++ operator new returns unexpected value - c++

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.

Related

Access child class functions from a vector of a parent class without downcasting

How can one access child class functions from a vector of a parent class without downcasting?
example:
class a {
public:
...
};
class b : public a {
double output() { // both child class have memeber function called output,
// but they return different data type.
return 0;
}
};
class c : public a {
bool output() { return false; }
};
// main
vector<a> vec;
b obj;
c obj2;
vec.push_back(obj);
vec.push_back(obj2);
for (int i = 0; i < vec.size(); i++) {
cout << vec[i].output();
}
Error:
error: no member function called "output" found in a
I have tried function overridding:
class a{
public:
auto output()
};
This approach don't work because I sometimes need to pass multiple parameters and this function doesn't allow that and will throw me the error: Function output expected 0 parameters, received x parameters.
It is possible like this
#include <iostream>
#include <vector>
struct result
{
enum
{
BOOL,
DOUBLE
} tag;
union ret {
double d;
bool b;
} r;
};
std::ostream &operator<<(std::ostream &s, const result &r)
{
switch (r.tag)
{
case result::DOUBLE:
s << r.r.d;
break;
case result::BOOL:
s << r.r.b;
break;
default:
break;
}
return s;
}
class a
{
public:
virtual result output() = 0;
};
class b : public a
{
result output() override
{
result r{result::DOUBLE, 132.};
return r;
}
};
class c : public a
{
result output() override
{
result r{result::BOOL, false};
return r;
}
};
int main(int argc, char const *argv[])
{
std::vector<a *> vec;
a *obj = new b;
a *obj2 = new c;
vec.push_back(obj);
vec.push_back(obj2);
for (int i = 0; i < vec.size(); i++)
{
std::cout << vec[i]->output() << std::endl;
}
return 0;
}
but its ugly. even more then

Obtain variable from derived class c++

I'm looking to do something only if the class is a specific derived class. That is I have:
class X{
int id;
}
class A: public X{
void run();
}
class B: public X{
int lala;
}
And I want to do something along the line of:
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0;
for(int i = 0; i<types.size(); i++){
if(types[i].isType(A)) {types[i].run();}
}
for(int i = 0; i<types.size(); i++){
if(types[i].isType(B)) {var = lala;}
}
}
I do not want class B to have anything equivalent to run(), nor do I want class A to have an equivalent to lala.
I know fortran has a workaround with
select type ( x => var )
class is ( A )
x.run()
end select
But I wasn't sure what my options in C++ were.
Thanks
You are looking for dynamic_cast.
#include <vector>
using namespace std;
class X {
public:
int id;
virtual ~X() = default;
};
class A : public X {
public:
void run() {}
};
class B : public X {
public:
int lala;
};
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0;
for(int i = 0; i<types.size(); i++){
if (auto ta = dynamic_cast<A *>(types[i])) {
ta->run();
}
}
for(int i = 0; i<types.size(); i++){
if (auto tb = dynamic_cast<B *>(types[i])) {
var = tb->lala;
}
}
}
Also see it in action here: https://onlinegdb.com/B1d29P5if.
I had to fix a few other problems with the code. Since they are not a part of your question, I won't clarify here, but you are welcome to ask if something is not clear.
EDIT: The above solution has memory leaks, which I didn't fix, as it wasn't required by the question. For completeness, here is the main function with memory leaks fixed (https://onlinegdb.com/ByeOmu9iz):
int main() {
vector<unique_ptr<X>> types;
types.emplace_back(new A);
types.emplace_back(new B);
int var = 0;
for(int i = 0; i < types.size(); ++i) {
if (auto ta = dynamic_cast<A *>(types[i].get())) {
ta->run();
}
}
for(int i = 0; i < types.size(); ++i) {
if (auto tb = dynamic_cast<B *>(types[i].get())) {
var = tb->lala;
}
}
}
Note that this is a C++11 solution.
If you're working with an even older compiler, you'll have to keep using plain pointers as in the original solution, and deallocate the memory manually at the end by calling delete on each element of the vector. (And hope nothing throws an exception before you reach that step.)
You'll also have to replace auto ta with A* ta and auto tb with B* tb.
A modern C++17 solution to this problem is to use a vector of variants, i.e. std::vector<std::variant<A, B>>. You need a modern compiler for this.
Here is a complete example, based on the std::variant documentation:
#include <vector>
#include <variant>
#include <iostream>
class X {
int id;
};
class A: public X {
public:
void run() {
std::cout << "run\n"; // just for demonstration purposes
}
};
class B: public X {
public:
B(int lala) : lala(lala) {} // just for demonstration purposes
int lala;
};
int main() {
std::vector<std::variant<A, B>> types;
types.push_back(A()); // no more new!
types.push_back(B(123)); // no more new!
int var = 0;
for (auto&& type : types) {
std::visit([&](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, A>) {
arg.run();
} else {
var = arg.lala;
}
}, type);
}
std::cout << var << '\n'; // just for demonstration purposes
}
As a nice bonus, this solution elegantly gets rid of dynamic allocation (no more memory leaks, no smart pointers necessary).
I have two ideas....
Why not have a shared method that returns a value that gives context as to whether or not it is an A or B? If for example, lala is expected to return only values 0 or greater, you could have void run() instead be int run() and return -1 at all times.
class X {
int id;
virtual int run() = 0; //Assuming X isn't meant to be instantiated
}
class A: public X {
// Return -1 to differentiate between As and Bs
int run() { return -1; }
}
class B: public X {
int lala;
int run() { return lala;}
}
Then you have...
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0, temp = 0;
for( int i = 0; i<types.size(); i++ ) {
if( (temp = types[i].run()) != -1 )
var = temp;
....
}
}
Again, only works if lala would never expect to return a particular range of values.
You could also hide information in X, upon creation of an A or B to keep track of what you have.
class X {
int id;
bool isA;
}
class A: public X {
A() : isA(true) { };
void run();
}
class B: public X {
B() : isA(false) { } ;
int lala;
}
Then you have...
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0;
for( int i = 0; i<types.size(); i++ ) {
if( types[i].isA == true ) {
types[i].run();
}
else {
var = types[i].lala;
}
}
Naturally if you expect to add C, D, E, .... it will no longer be worth it, but for only two derived classes it isn't all that bad.
I would justify this based on the fact that users are already going to have to peer into the derived classes to see why they behave so differently for being derived from the same class. I would actually look into whether or not it makes sense for A and B to derive from X based on their interface.
I also wouldn't recommend dynamic_cast(ing) without informing someone that it's one of the more dangerous casts to perform and typically not recommended.
You could use dynamic_cast to check if the base class pointer is convertible to a derived instance.
Another option would be to have a virtual function that returns the typeinfo of the class and thus use that information to cast the pointer to a convertible type. Depending on how dynamic_cast is implemented this could be more performant. Thus, you could use this if you want to try and see whether or not this method is quicker on your platform.
As #Jarod42 noted, you would need to have a virtual function, destructor in this case, for dynamic_cast to work. In addition, you would simply need a virtual destrctor to avoid undefined behavior when deleting the instance.
Example
#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>
struct A {
virtual ~A() {
}
virtual const std::type_info& getTypeInfo() const {
return typeid(A);
}
};
struct B : public A {
virtual const std::type_info& getTypeInfo() const override {
return typeid(B);
}
};
struct C : public A {
virtual const std::type_info& getTypeInfo() const override {
return typeid(C);
}
};
int main()
{
std::vector<A*> data;
data.push_back(new A);
data.push_back(new B);
data.push_back(new C);
for (auto& val : data) {
if (val->getTypeInfo() == typeid(A)) {
std::cout << "A";
}
else if (val->getTypeInfo() == typeid(B)) {
std::cout << "B";
}
else if (val->getTypeInfo() == typeid(C)) {
std::cout << "C";
}
std::cout << std::endl;
}
for (auto& val : data) {
delete val;
}
}

c++ how to call function with subclass, having superclass pointer

I have 3 classes, A, B and C:
class A {
public:
virtual bool sm(B b) = 0;
virtual bool sm(C c) = 0;
};
class B : public A {
bool sm(B b) {
//code
}
bool sm(C c) {
//code
}
};
class C : public A {
bool sm(B b) {
//code
}
bool sm(C c) {
//code
}
};
And vector<A*> objects, that stores B or C objects. (for example they generates randomly)
Can I call somehow
for(int i = 0; i < objects.size(); i++) {
for(int j = i; j < objects.size(); j++) {
objects[i].sm(objects[j]);
}
}
Without dynamic cast or something? Because there can be a bit more of B-C classes
And is it a bag thing, and may be there is a better way to do it?
SOLUTION
As odelande said and I understood, this is the solution for my problem
#include <iostream>
#include <vector>
class B;
class C;
class A {
public:
virtual bool sm(A* a) = 0;
virtual bool sm(B* b) = 0;
virtual bool sm(C* c) = 0;
};
class B : public A {
public:
bool sm(A* a) {
return a->sm(this);
}
bool sm(B* b) {
std::cout << "In B doing B" << std::endl;
return true;
}
bool sm(C* c) {
std::cout << "In B doing C" << std::endl;
return false;
}
};
class C : public A {
public:
bool sm(A* a) {
return a->sm(this);
}
bool sm(B* b) {
std::cout << "In C doing B" << std::endl;
return true;
}
bool sm(C* c) {
std::cout << "In C doing C" << std::endl;
return false;
}
};
int main() {
std::vector<A*> objects;
objects.push_back(new B());
objects.push_back(new C());
objects[0]->sm(objects[0]);
objects[0]->sm(objects[1]);
objects[1]->sm(objects[0]);
objects[1]->sm(objects[1]);
std::cin.get();
return 0;
}
This code outputs
In B doing B
In C doing B
In B doing C
In C doing C
You cannot do it like this. The overloads of the sm() method are statically resolved, i.e. at compile time (besides, sm() should take pointers to B and C). But the compiler only knows that objects[j] is an A*; it cannot resolve the call because there is no overload that takes a A* as input.
What you want is to dispatch the call based on the runtime type of objects[j]. This is what a call to a virtual function does. So, you should only have one sm() method, which should in turn call another virtual method of its argument.
You're searching for the Visitor Pattern, multiple dispatch. The key is that you take a reference in sm(A& a) and call smT(...) on it. (Code is for example purposes only, will need clean-up and consts.)
class A {
protected:
virtual bool smB(B& b) = 0;
virtual bool smC(C& c) = 0;
public:
virtual bool sm(A& a) = 0;
};
class B : public A {
protected:
bool smB(B& b) {
// code,
}
bool smC(C& b) {
// code
}
public:
bool sm(A& a) {
a.smB( *this ); // this is smC(...) in class C
}
};

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

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

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