extending base class by casting it to derived and setting the data - c++

Assume I have this:
class Base {
public:
int a;
Base() : a(5) {}
};
template<class T>
class Derived : public Base {
public:
T value;
};
The code below works but I want to know what can be the challenges of using such approach:
Base * base = new Base;
Derived<int> * derived = static_cast<Derived<int>*>(base);
derived->value = 5;
Derived<String> * derived1 = static_cast<Derived<String>*>(base);
derived1->value = "test";
Derived<String> * newderived = static_cast<Derived<String>*>(base);
std::cout << newderived->value;
Derived<int> * newderived1 = static_cast<Derived<int>*>(base);
std::cout << newderived1->value;
//Output: test1
Or how can I achieve such thing in a different, safer way. I want to pass a class through 5 functions that will manipulate it.

What you're doing here will fail horribly at some point because the size of the derived class is larger than the base class and you write after the end of the base class. The above write operation will overwrite memory that belongs to another object.
You can have a SetValue() method in the base class and implement it in the derived class.

The code does not work. All you objects even after casting are still a Base because you constructed them as a base. The casts just say: Hey, I know it's a Derived<xxx>, so please just interpret that this way. You don't know this here, in fact you know it is NOT a Derived.
To properly use the objects, you need to create a Derived<xxx> and afterwards cast. If you use a dynamic_cast here all cases should come back as null as they are Base.
Given that you wanted to "pass a class through 5 functions" you'd probably want the inverted setup. Create Derived<xxx> objects and hold them as a pointer to Base. This works without casting as it should. Then pass the Base* through your functions. Polymorphism will take care that everything works fine.

Related

Create a fully-functional derived class with just one extra method in C++?

This is what I want to do:
class Derived : public Base
{
public:
int someNewMethod(int someIntParam)
{
// Does something not in the base class
return 0; // success
}
};
Then I should be able to use Derived in place of Base (while fully aware that the reference may become invalid, depending on when the Base object is deleted):
Derived &d = *pointerToSomeExistingBaseObject;
d.someNewMethod(12);
While somewehere else in code, far, far away (and beforehand):
Base *pointerToSomeExistingBaseObject = new Base(...);
Thank you!
Create a fully-functional derived class with just one extra method in C++?
You can do that. You did that with Derived (assuming someNewMethod isn't in Base).
Derived &d = *pointerToSomeExistingBaseObject;
d.someNewMethod(12);
While somewehere else in code, far, far away (and beforehand):
Base *pointerToSomeExistingBaseObject = new Base(...);
No, you cannot do that. In order to call the non-static member functions of Derived, you must create an object of type Derived or a type derived from it.
The typical solution is to make the function free-standing:
int someNewMethod(Base& obj, int someIntParam)
{
// Does something with obj that is not in Base
return 0; // success
}

Upcast using reference in C++

I would like to use the "Strategy" design pattern, and have just one simple question.
We have two classes: Base as an abstract class and Derived as a concrete class.
#include <iostream>
using namespace std;
class Base {
public:
virtual void func() = 0;
};
class Derived : public Base{
public:
virtual void func() override
{
printf("hello \n");
}
};
int main(){
Base * base = new Derived();
base->func();
Derived derived2;
Base & base2 = derived2;
base2.func();
return 0;
}
Using pointer,
Base * base = new Derived();
Using reference
Derived derived2;
Base & base2 = derived2;
Is there any way to write in one line for reference?
Which method are you guys use to implement the "strategy" design pattern,
using pointer or reference?
Because of the reason above, I tend to use pointer... but I would like an answer from experts.
Is there any way to write in one line for reference?
You could use static_cast<Base&>. This produces a reference to the Base portion of your object :
int main() {
Derived derived2;
static_cast<Base&>(derived2).func();
return 0;
}
Which method are you guys use to implement the "strategy" design pattern, using pointer or reference?
You don't usually see references used for this because most of the time you need to store your polymorphic object and that's not practical with references. References refer to an object, but that object needs to otherwise exist somewhere else.
Notice that your first case creates a dynamically allocated instance, you can pass the pointer around easily. The second one creates a local object which is much harder to move around polymorphically. If you try to store your Derived object into a container, you'll certainly need to dynamically allocate it anyway. Trying to do otherwise will result in object slicing (where the derived portion is entirely sliced off).
For example, this is how you would store a Derived into a container of Base pointers :
int main()
{
std::vector<std::unique_ptr<Base>> my_bases;
my_bases.emplace_back(std::make_unique<Derived>());
}
If you tried to use a std::vector<Base> it wouldn't compile (Base is abstract). But even if it did compile (by making Base concrete) it would not behave polymorphically. This is not unique to the strategy pattern. This is how it works whenever you employ polymorphism.

Call an interface function from an unknown derived class (multiple inheritance)

I have an array of Base* objects. This holds a bunch of derived objects, some of which may implement an Interface.
struct Base {
virtual void doNotCallThis() { cout << "nooo" << endl; }
};
struct Interface {
virtual void doThis() = 0;
};
// Example derived class
struct Derived : Base, virtual Interface {
virtual void doThis() { cout << "yes" << endl; }
};
int main() {
Base* b[1];
b[0] = new Derived(); // Here would be a bunch of different derived classes
((Interface*)b[0])->doThis(); // Elsewhere, doThis() would be called for select array elements
return 0;
}
Output:
nooo
I don't know the exact type of b[i] at run time, so I can't cast to Derived (it could be Derived2, Derived3, etc). I also can't use dynamic_cast if that's a solution. All I know is that, by the time I call doThis(), b[i] is a type that inherits from Interface. The way I attempted to call it above causes the wrong function to be called, eg. Base::doNotCallThis().
How can I call it properly?
As other people have pointed out, you would probably do best to find a way to refactor your design so that casting isn't necessary.
But putting that aside, I can explain what's going wrong and how to correctly cast.
The problem with ((Interface*)b[0]) is that since Base and Interface are unrelated the compiler has to do a blind reinterpretive cast. Practically speaking that means in this situation the resulting pointer doesn't actually line up with the Interface part of the object. If you were to try static_cast<Interface*>(b[0]) you would find it doesn't compile - and that's a big hint that it's the wrong kind of cast to be making.
On the other hand, the compiler does know the relationship from Base to Derived and also from Derived to Interface. So as long as you know for sure that the object not only implements Interface but also is a Derived then you can do:
static_cast<Interface*>(static_cast<Derived*>(b[0]))->doThis();
However if your design has multiple different derived types which independently implement Interface then you might not be able to do that unless again you absolutely know what the derived type is at any time you go to make the call. - This is why refactoring it into a better class hierarchy is more desirable, since it's much less fragile and cumbersome to work with.
(As a side note, this issue points out why it's a great idea to never use raw/reintrepretive casts when moving up and down a class hierarchy. At least use static_cast since the can compiler better help you do it correctly.)
Writing an answer with the risk of being downvoted:
If we start with::
struct Base()
{
virtual void SomeFunc();
};
struct Interface
{
virtual void doThis();
}
then to create a bunch of derived functions from Base that are also interfaces, I'd do something like this:
struct BaseInterface : public Base, public Interface
{
// Nothing here - this is just combining Base and Interface
};
struct Base1 : public BaseInterface
{
... add stuff that Base1 has that isn't in Base.
};
struct Derived: public Base1
{
... some more stuff that isn't in Base1
}
And then we use it in Main like this:
int main() {
BaseInterface* b[1];
b[0] = new Derived(); // Here would be a bunch of different derived classes
b[0])->doThis(); // Elsewhere, doThis() would be called for select array elements
return 0;
}

linking vector of derived class type to vector of parent class type in C++

I am in beginner stage of C++. Suppose I have a base class and a derived class:
class Base{
....
}
class Derived:public Base{
....
}
Now I have two vectors as follows, I will perform some operations to some create base and derived objects and push these objects back to their corresponding vectors respectively:
std::vector<Base*> baseVector
std::vector<Derived*> derivedVector
I want to point each of the element(object) of derivedVector to each of the element(object) of the baseVector. Suppose derivedVector[2] will have a pointer to baseVector[2] so that at any time I can access the base object from my derived object. How should I do this?
It's not very clear what you mean, but if I understand correctly you want to put pointer to your Derived object in two vectors. You can achieve it this way:
baseVector[2] = derivedVector[2] = new Derived();
I think this is the important part of your question:
... so that at any time I can access the base object from my derived object.
And the answer is fairly simple. With inheritance, the derived object can already access its base object. That's the whole point of inheritance.
You can keep it simple:
class Base{
SomeBaseFunction();
}
class Derived : public Base{
// Do not add a Base* here.
}
int main() {
Derived *derived_object = new Derived();
derived_object->SomeFunction(); // this works.
}
You should think more clearly about your vectors here. You probably only need one vector, not two. Also, you should probably deal with vector<Derived>, not vector<Derived*>.
int main () {
Derived derived_object; // don't use `new` here, it's just awkward
vector<Derived> vector_of_objects;
vector_of_objects.push_back(derived_object);
}
In modern C++, whether you're a beginner or an expert, you shouldn't use * or new very often.
See if you want to use base list to contain derived object pointers then it is ok. but you can't use derived list to hold base pointers.
may be you want something like.
Base * pBase = new Base();
Derived *pDerived_1 = new Derived();
// or
Base *pDerived_2 = (Base *)new Derived();
// this can be anytime casted back
Derived *pDerived_3 = (Derived*)pDerived_2;
// you can also push them into base vector
lstBasePtr.push_back(pBase);
lstBasePtr.push_back(pDerived_1);
lstBasePtr.push_back(pDerived_2);
lstBasePtr.push_back(pDerived_3);
Hi thanks for your response. I have figured out what I needed to do. Not sure if its the smartest way, if not please suggest me.
Here is how I did it:
class Base{
SomeBaseFunction();
}
class Derived:public base{
//I have put a pointer of base type here
base *basePointer;
}
Now in the main function where I basically populate the base and derived vector, I do the following:
derivedObject->basePointer = baseObject;
Now I can access the base properties as follows:
derivedObject->basePointer->SomeBaseFunction();

Instantiation of objects in conditionals c++

let's say I want to instantiate a different type of object depending on certain circumstances, so i would instantiate them inside the body of an if statement. The problem is if you want to use that object later, you need to declare it before instantiation. How does one declare a generic object. Is there something similar to the object class in Java?
I've done some google searching like "generic object c++" and "object class c++" and there doesn't appear to be something like that.
This problem can be solved with interfaces. Now, C++ doesn't know interfaces, but you can easily do something similar with abstract base classes:
class Base { ... }
class A : public Base { ... } // A is a Base
class B : public Base { ... } // B is a Base
...
Base *X; // that's what you will end up using
if (some_condition)
X = new A(); // valid, since A is a Base
else
X = new B(); // equally valid, since B is a Base
This will require you to put common functionality into the base class so that you can actually perform operations on X.
(If you derived all your classes from something like Base, you'd end up with a super-class like it's available in e.g. C# or Java. However, in my opinion, generic programming, ie. templates in C++, have much reduced the need for a super-class like that. I'd wager that you'll be able to find better code designs in most cases.)
Unlike Java, C++ has no "mother" object which all classes inherit from. In order to accomplish what you're talking about, you'd need to use a base pointer of your own class hierarchy.
Animal* a;
if (...) a = new Cat();
else if (...) a = new Dog();
Also, because there's no garbage collection either, it's better to use smart pointers when you do this sort of thing. Otherwise, be sure you remember to delete a. You also need to make sure that Animal has a virtual destructor.
There's no "ancestor of all classes" in C++. But there are some options for doing similar things.
As stakx suggests, make a base class if possible. This is the best from an object-oriented design perspective. Are there common operations that you want to apply to all the objects? If so, try to write an interface, and make the interface a base class. Alternatively, you can use templates to get compile-time polymorphism instead of runtime polymorphism.
If this is too difficult, then look at a wrapper class like boost::any. That can hold any (copyable) type. It's an opaque wrapper, and you have to know the exact type of data that was put into it, to get it back out. For example, if you put in a Derived *, you need to use boost::any_cast<Derived *>(wrapped) to get the data back - boost::any_cast<Base *>(wrapped) won't work.
std::shared_ptr<Base> X( some_condition ? new A() : new B() );
Heap solutions are expensive and error prone. For not too heavy objects without heap allocations on construction the following approach is preferrable:
Derived1 d1;
Derived2 d2;
Base * b = 0;
if (useD1) {
b = &d1;
} else {
b = &d2;
}
Here we peallocate both types we might need on the stack. No heap allocation, no delete operators, no smartpointers. The only problem - doesn't scale to complex classes to be preallocated.
There is no common base class in C++, so you should define such common ancestor yourself if you the author of these classes or you can use void* although I wouldn't recommend the latter.
If you can't modify the classes then you can introduce wrappers that implement the interface that you need as illustrated below:
class A {};
class B {};
class MyBase
{
// Define the interface that you need.
};
class MyA : public MyBase
{
private:
A a;
public:
// Implement MyBase in terms of A.
};
class MyB : public MyBase
{
private:
B b;
public:
// Implement MyBase in terms of B.
};
int main ()
{
MyBase* base = 0;
if (useA)
base = new MyA();
else
base = new MyB();
}