For instance I have code like that
class Base1
{
virtual void wonderFULL() = 0;
};
class Base2
{
// all this weird members
};
class Derived : public Base1, public Base2
{
// not so weird members
};
int main()
{
Derived Wonder;
magicFunction(&Wonder);
return 0;
}
void magicFunction(Base2 *ptr)
{
if (Base1 *b1 = dynamic_cast<Base1 *>(ptr))
b1->wonderFULL();
}
However wonderFULL is never executed due to impossibility to cast ptr to b1. Is it possible at all to perform such a conversion?
This
#include <iostream>
class Base1 {
public:
virtual void wonderFULL() = 0;
};
class Base2 {
public:
virtual ~Base2() {} // added so the code compiles
};
class Derived : public Base1, public Base2 {
virtual void wonderFULL() {std::cout << "wonderful\n";} // added so the code compiles
};
void magicFunction(Base2 *ptr) {
if (Base1 *b1 = dynamic_cast<Base1 *>(ptr))
b1->wonderFULL();
}
int main() {
Derived Wonder;
magicFunction(&Wonder);
return 0;
}
prints wonderful for me. My conclusion is that you're not showing the code necessary for your problem to reproduce.
Take (a copy of) your actual code and by removing uneccessary code step by step distill it until you derive at a self-contained (needs no other headers except from the std lib), compilable example that reproduces the problem. Very likely you will find the problem while doing so. However, if you don't, you have the perfect repro case to come back here and ask about.
You have some syntax errors, but your real problem is dynamic_cast won't work properly if your base classes don't have at least one virtual function.
If you make it look like:
class Base2
{
public:
virtual ~Base2() {}
// all this weird members
};
And then fix your other errors:
wonderFULL is private, and never defined.
magicFunction is declared after it is used.
Then everything works.
You can cast up the hierarchy then back down:
void magicFunction(Base2& ptr)
{
try
{
Derived& d = dynamic_cast<Derived&>(ptr);
Base1& b = dynamic_cast<Base1&>(d);
b.wonderFULL();
}
catch(const std::bad_cast&)
{ /* Cast failed */ }
}
Going by what I understand of the way some C++ compilers arrange the class hierarchy in memory it should be possible to cast from one base class to another, but you have to first cast to the derived class.
Therefore you would need to do something like:
Base1* b1 = dynamic_cast<Derived*>(ptr);
This casts the given pointer ptr to the derived class, and then it gets implicitly cast to its other base class pointer.
However another easier way to do this would be to just have a method in the Base2 class that returns a Base1 pointer, and the derived class can implement this itself without any tricky code. (The same function in Base2 can just return NULL if you don't want a pure virtual class).
I've found the problem. It was not about dynamic_casts. I was checking wrong object which was not inherited from abstract base. Thanks.
Related
I want to retrieve the initial type in the base class A because the method encodeMsg() will have tasks that are related to the derived type
#include "stdafx.h"
#include <iostream>
struct base {
};
struct derive : base {
};
class A{
public:
A(){}
virtual void encode() {
encodeMsg(_bStruct);
// here I want to cast base to derive but I don't know how I tried
// static_cast<decltype(this)>(_bStruct) but it seems doesn't work
}
virtual void setStruct(base* bStruct) {
_bStruct = bStruct;
}
private:
virtual void encodeMsg(base* bStruct) = 0;
protected:
base* _bStruct;
};
class B : public A {
public:
B(){}
void encodeMsg(base* bStruct) {
derive* _dStruct = static_cast<derive*>(bStruct);
// ..
// stuff within dervied struct
_bStruct = static_cast<base*>(_dStruct); // turn back to base struct
}
};
int main() {
B b;
base* _bStruct = new derive();
b.setStruct(_bStruct);
b.encode();
return 0;
}
The question makes no sense.
In your code, the only thing you could do with the pointer, if you could create it, is access members known to be in the base class. But you can do that already without the pointer. So what purpose does the pointer serve?
If you want to one thing if it's a derived1 and something else if it's a derived2, then you need to use one piece of code for the derived1 case and one piece of code for the derived2 case.
If you want to do the same thing regardless of what derived type it is, there is no need for the cast you seek. The code in this function will be the same regardless of what the derived type is.
If you want code that only works if the derived type is some specific type, use a dynamic_cast to a pointer to that type and write the specific code. If you want code that works regardless of the derived type, use a pointer to an instance of the base class.
Update:
To access members not in base but in a derived1, use this code:
virtual void encode() {
derived1* d1 = dynamic_cast<derived1*>(bStruct);
if (d1 != nullptr)
{
// here you can access d1->whatever
}
}
I have the following code:
class Base
{
public:
virtual void doSomething() = 0;
};
class BaseImpl : public virtual Base
{
public:
virtual void doSomething() {
// something
}
};
class BaseDerived: public virtual Base
{
public:
virtual void doSomething2() = 0;
};
class BaseDerivedImpl: public BaseImpl, public BaseDerived
{
public:
virtual void doSomething2(){
// sonething2
}
};
Then I have
Base* b = new BaseImpl();
b->doSomething(); // fatal error at this line (not in the method, but in the method invocation)
The problem is that it even does not go into the function.
Is it something wrong with using such hierarchy?
As OP ignores the comments, let me answer the question here:
Is it something wrong with using such hierarchy?
No, nothing is wrong. This is the standard way how to solve the 'dreaded diamond' issue (which isn't actually all that dreadful).
However, the diamond doesn't even come to play in this example:
Base* b = new BaseImpl();
BaseImpl is derived directly from Base so you have standard single inheritance. Your code behaves the same as if BaseDerived and BaseDerivedImpl were not defined at all. You can comment them out, and the app will still crash.
Then you call doSomething on this instance and it crashes. The implementation of doSomething is as follows:
// something
Thus, my conclusion is that // something results with crash, but it is impossible to tell without seeing the implementation of that method.
Please look at this code. It just reflects basic concept of what I want to do:
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
/* Some code I want to reuse */
Redefined();
}
virtual ~Base() {}
void Redefined() { val = 10; }
int val;
};
class Derived : public Base
{
public:
Derived() : Base() {}
~Derived() {}
void Redefined() { val = 25; }
};
int main()
{
Base* check = new Derived();
cout << check->val << endl;
system("pause");
return 0;
}
I want the val property of check object to be 25 instead of 10.
As you can see I have two classes. Base class constructor have some complex functionality, which I want Derived class to have in it's constructor as well. How can I change derived function Redefined so that I won't have to rewrite Derived constructor completely (in fact just copy-pasting the whole base class constructor code and replacing one single line of code - updated version of Redefined function)?
You can't really override a function that way. Normally you could use a virtual functions, but that doesn't work the way you want in the constructor.
A better way is to pass the value you want to the Base constructor:
class Base
{
public:
Base(int init_val = 10)
{
/* Some code I want to reuse */
val = init_val;
}
virtual ~Base() {}
int val;
};
class Derived : public Base
{
public:
Derived() : Base(25) {}
~Derived() {}
};
That way any derived class can pass its choice of value to the base class.
Based on comments above:
I would actually think that the correct solution is to have a "interface" type baseclass (that is, a baseclass with pure virtual functions, and the derived class actually implements the correct behaviour), and then let each class deal with constructing its own DirectX buffers. You may find that you need, say, 2-3 different derived classes that construct buffers in different ways, and then derive from those the classes that actually do the real work. I hope that makes sense.
Alternatively, you would be passing enough parameters to the base-class, such that the buffers can be constructed. But I think the first suggestion is a better choice.
This compiles fine, although I wouldn't want to try running it just yet. However ...
//class base;
//class derived;
//class derived : public base;
class base {};
class derived : public base {};
class other
{
public:
void func() {base1 = derived1;}
base* base1;
derived* derived1;
};
void main()
{
}
... moving the class other to above the definition of base and derived for which there is a similar thing I must do in a program of myne causes compile errors.
The obvious solution is to forward declare base and derived shown commented out at the top of the code, however this causes a can't convert between base* and derived* error. Attempting to forward declare including the inheritance information dosn't work either.
This should work. You need to move other up
BUT declare func below. That way func is able to "see" that derived is of type base.
e.g.,
class base;
class derived;
//class derived : public base;
class other
{
public:
void func();
base* base1;
derived* derived1;
};
class base {};
class derived : public base {};
void other::func() { base1 = derived1; }
There is no syntax for forward-declaring two classes and specifying that one inherits from the other. This is because inheritance can be complex (multiple and/or virtual), so the assignment base1 = derived1 might involve some arithmetic, and it's difficult/impossible for the compiler to generate that arithmetic when it only knows that derived inherits from base.
So, to solve your problem, you can make func not inline (see the answer from AbstractDissonance), or, if you absolutely need it to be inline, use reinterpret_cast:
class base;
class derived;
class other
{
public:
void func() {base1 = reinterpret_cast<base*>(derived1);}
base* base1;
derived* derived1;
};
This is bad because it is not guaranteed to work by the C++ standard, and it will almost certainly not work if you use multiple/virtual inheritance. Use this only if func has to be as fast as possible (i.e. inline), and if you don't need your code to be portable.
I'm slightly confused about runtime polymorphism. Correct me if I am wrong, but to my knowledge, runtime polymorphism means that function definitions will get resolved at runtime.
Take this example:
class a
{
a();
~a();
void baseclass();
}
class b: class a
{
b();
~b();
void derivedclass1();
}
class c: class a
{
c();
~c();
void derivedclass2();
}
Calling methodology:
b derived1;
a *baseptr = &derived1; //here base pointer knows that i'm pointing to derived class b.
baseptr->derivedclass1();
In the above calling methodology, the base class knows that it's pointing to derived class b.
So where does the ambiguity exist?
In what cases will the function definitions get resolved at runtime?
This code, at run time, calls the correct version of f() depending on the type of object (A or B) that was actually created - no "ambiguity". The type cannot be known at compile-time, because it is selected randomly at run-time.
struct A {
virtual ~A() {}
virtual void f() {}
};
struct B : public A {
virtual void f() {}
};
int main() {
A * a = 0;
if ( rand() % 2 ) {
a = new A;
}
else {
a = new B;
}
a->f(); // calls correct f()
delete a;
}
There is no ambiguity exists in the example provided.
If the base class has the same function name as the derived class, and if you call in the way you specified, it will call the base class's function instead of the derived class one.
In such cases, you can use the virtual keyword, to ensure that the function gets called from the object that it is currently being pointed. It is resolved during the run time.
Here you can find more explanation..
Turn this
void baseclass();
to
virtual void baseclass();
Override this in your Derived classes b and c. Then
b *derived1 = new derived1 ();
a *baseptr = derived1; //base pointer pointing to derived class b.
baseptr->baseclass();
will invoke derived1 definition, expressing run time polymorphism. And do remember about making your destructor virtual in Base. Some basic reading material for polymorphism
Runtime means that exact method will be known only at run time. Consider this example:
class BaseClass
{
public:
virtual void method() {...};
};
class DerivedClassA : public BaseClass
{
virtual void method() {...};
};
class DerivedClassB : public BaseClass
{
virtual void method() {...};
};
void func(BaseClass* a)
{
a->method();
}
When you implement your ::func() you don't know exactly type of instance pointed by BaseClass* a. It might be DerivedClassA or DerivedClassB instance etc.
You should realize, that runtime polymorphism requires special support from language (and maybe some overhead for calling "virtual" functions). In C++ you "request" for dynamic polymorphism by declaring methods of base class "virtual" and using public inheritance.
You need to have some useful business method declared in the base and in each derived class. Then you have code such as
a->someMethod();
Now the a pointer might point to an instance of any of the derived classes, and so the type of what a is pointing to must determine which someMethod() is called.
Lets have an experiment
#include <iostream>
using namespace std;
class aBaseClass
{
public:
void testFunction(){cout<<"hello base";}///Not declared as virtual!!!!
};
class aDerivedClass:public aBaseClass
{
public:
void testFunction(){cout<<"hello derived one";}
};
class anotherDerivedClass:public aDerivedClass
{
public:
void testFunction(){cout<<"hello derived two";}
};
int main()
{
aBaseClass *aBaseClassPointer;
aBaseClassPointer=new aDerivedClass;
aBaseClassPointer->testFunction();
}
The above code does not support run time polymorphism. Lets run and analyze it.
The output is
hello base
Just change the line void testFunction(){cout<<"hello base";} to virtual void testFunction(){cout<<"hello base";} in aBaseClass. Run and analyze it. We see that runtime polymorphism is achieved. The calling of appropriate function is determined at run time.
Again change the line aBaseClassPointer=new aDerivedClass to aBaseClassPointer=new anotherDerivedClass in main function and see the output. Thus the appropriate function calling is determined at run time (when the program is running).