Hello :) i would like to ask, if it's posible to make something like this:
i have base class (parent) A and three other classes (childs) B C D
in class A, i have virtual functions, that's ok.
but what if i need a virtual class ?
class A
{
public:
virtual int func1()=0;
virtual int func2()=0;
virtual class AB; // !!!!???
};
class B
{
public:
int func1();
int func2();
class AB
{
public:
....
};
};
classes B C D are same as class B. Now, i would like to create class instance and it should automaticly "redirect" class to instance of B or C D etc like functions.
is it possible ? i hope, you understand :) Thank you very much for answer.
This is fundamentally impossible. A virtual function call is determined at runtime. A class changes the behaviour of the program at compile-time. You can't make a compile-time determination at runtime unless runtime and compiletime are the same time, i.e. using a JIT or other dynamic code generators. In standard C++, this is impossible.
What you CAN do is have a base class AB, with a virtual function that creates a class that is guaranteed to inherit from this base class, and then return a pointer to that.
Related
Hi I know the title is a little hard to understand, and that's just because I have no idea how to phrase this problem. Fortunately, I can provide an easy-to-understand example of my problem. Imagine a base class A derived class B and unrelated class C setup as follows:
class A
{
public:
};
class B : public A
{
public:
C c;
};
class C
{
public:
void foo();
};
I want to know how to call foo() using an object of class B without doing this:
B b;
b.c.foo();
but rather this:
B b;
b.foo();
Additionally, I don't want to inherit from class C or make copies of class C's functions. Is this possible with a simple implementation? Thanks!
Your constraints mean your example does not make sense unless the function foo is static; if it is not then you need to provide information about the instance of C you are using before foo makes sense; so mentioning c would be essential. If it is static then C::foo works but not b.foo(). If you want a member function for B that calls b.c.foo() then you should write one as suggested above.
Perhaps you meant to privately inherit C in B:
class B : private C , public A
{
public:
using C::foo;
};
will do the trick.
The situation is (hopefully) clear with the code. We have two (in this example pure abstract, but that isn't necessary) classes. Is this possible to define the class C? What happens to the pointer c_ptr? Do I need to delete it in the class B destructor?
class C : public B {
private:
public:
C();
~C();
int do();
};
class B : public A {
private:
C *c_ptr;
public:
B(){
c_ptr = new C();
}
~B() {
delete c_ptr;
}
virtual int do() = 0;
};
class A {
private:
public:
A();
~A();
virtual int do() = 0;
};
In short, no, this is not possible.
In your example we have the following constraints:
B is child of A
C is child of B is child of A
For every super class, there must be an object created as well. So for the instantiation of a B, there will be created an A first.
The same way for a C there will be constructed a B which will create an A first.
As C++ is a procedural language, datatypes and functions must be known BEFORE using them. However, it is not possible for the compiler to know how to build a C before knowing how to build a B and vice versa. Therefore it is not possible to do so.
However, this polymorphism structure may be accomplished by using something called Forward Declaration. Basically you tell the compiler that there is some class C which will be specified later on. Example in CompilerExplorer
For example, I have an abstract base class A and B. A has a virtual method as follows
class A
{
public:
virutal void f(B& b) = 0;
};
For class A1
class A1 : public A
{
public:
void f(B& b) override { b.f(A1); }
};
And thus for B, it needs a virtual method f(A1)
class B
{
public:
virtual void f(A1& a) = 0;
};
And in class B1 : public B, the virtual method is implemented. The problem is that when another class A2 : public A is added, I have to add a virtual method virtual void f(A2& a) = 0 in class B, which I think it breaks the code because I don't know if A2 even A1 is added or not when I design class B. How to avoid it but implement the equivalent requirements? Any C++ feature can be used even with templates.
Unfortunately, there's no such thing as a virtual template function in C++ (this is what I believe you're trying to accomplish, after parsing your question).
The closest, and the least ugly solution I can think of, is to have the virtual function in base class B take the base class A as a parameter:
class B
{
public:
virtual void f(A& a) = 0;
};
B1 overrides that, and then uses dynamic_cast to cast its parameter to an instance of A1.
In this manner, you can continue an define each Ax and Bx pair of derived classes, without having to change the API interface in the base class, between the two hierarchies.
A bit ugly, but the question states "any C++ feature can be used", and dynamic_cast certainly qualifies under that requirement.
Say we have a class inheriting from two base classes (multiple inheritance). Base class A is abstract, declaring a pure virtual function foo, the other base class B declares and implements a function foo of the very same signature.
struct A
{
virtual void foo(int i) = 0;
};
struct B
{
virtual void foo(int i) {}
};
struct C : public A, public B {};
I want to use the implementation of foo from base class B in my derived class C. However, if I do not implement the function foo a second time in my derived class C, I cannot instantiate any object of it (it remains abstract). Virtual inheritance does not help here as expected (class A and class B have no common base class).
I wonder if there is a way to "import" the implementation of foo from class B into class C in order not to have to repeat the same code.
Above example is of course contrived. The reason I want implement foo in class B is that I want to derive class D : public B and use class Bs implementation of foo. I know that inheritance is not (primarily) intended for code reuse, but I'd still like to use it in that way.
In java, your sample code works. In C++ it doesn't. A subtle difference between those languages.
Your best option in C++ is to define C::foo() by forwarding to B::foo():
struct C : public A, public B
{
virtual void foo(int i) { B::foo(i); }
};
I have class C and it is inheriting from Class A and Class B.
Is it possible for class A to access Class B function( eg fun1() ) using this inheritance. A and B are both independent class and fun1() is only in class B.
Not strictly through inheritance. Although A and B are parents of C, A and B have no relationship and no way to access eachother.
It is possible through inheritance and polimorphism, then class A have a virtual method that C implements calling the function in B, like this:
class A {
public:
b get_b() { return do_get_b(); }
private:
virtual do_get_b() = 0;
};
class B {
public:
b some_b;
};
class C : public A, public B {
private:
virtual do_get_b() {return some_b;}
}
You could check with dynamic_cast to see if your object of A is really a object of C, and thereby of B
void A::foo()
{
B* pB = dynamic_cast<B*>(this);
if (pB) pB->bar();
}
But if A and B are really independent of one another it is probably better to find a different solution.
Sometimes, it is possible. An example how to achieve this.
That example applies to a diamond hierarchy, which is a bit more complicated than yours. In your terms, ClassA and ClassB should be derived from class Base, ClassC is derived from ClassA and ClassB.