Create object that inherits from base-class - c++

Maybe this is a bit of a beginner's question but I need some help regarding this issue.
Assume there is a class A that inherits from class B that itself inherits from class C.
Now when class A constructor looks like this everything is fine:
A::A(params)
:B(params)
{
}
Next I tried this but it fails:
A::A(params)
:C(params)
{
}
Why can't I ignore inheritance from B here - or is there a way to make this possible? Defining A as follows does not work, here compiler complains C is already a base class of A:
class A : B, C

Why can't I ignore inheritacne from B here - or is there a way to make this possible?
Because classes can only decide how to construct their direct subobject. The direct subobject for A is B and for B is C. The B object needs to be constructed too, you can't bypass it.
The error you got, basically complains about this.
Defining A as follows does not work, here compiler complains C is already a base class of A: class A : B,C
With:
class A : B, C
you are actually declaring a private multiple inheritance. And since you said B has already a subobject (inherits from) C, the compiler is complaining that inheriting from C in A is useless.
But please remember to always specify the private/protected/public kind of inheritance so that you avoid confusion. By default the inheritance for classes is private and for structs is public. So the above code corresponds to:
class A : private B, private C

You should write:
class C
{
public: C(ParamType param) { ... }
};
class B : public C
{
public: B(ParamType param) : C(param) { ... }
};
class A : public B
{
public: A(ParamType param) : B(param) { ... }
};
There is really no other way....

Related

C++ How to Refer to a Class' Members' Members Without Accessing Original Member

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.

Upcasting to a C++ class that is a base class in more than one way (without having to use virtual inheritance)

class A { };
class B : public A {};
class C : public A, public B {};
int main()
{
C c;
A *pA = static_cast<A *>(&c);
}
In the above code, class C is derived from class A in two different paths:
1. Directly from A
2. Indirectly through B i.e. A<-B<-C
So, when I cast an object of class C into a pointer to class A, g++ on Linux reports the following error:
error: A is an ambiguous base of C
I have also tried the same code by removing the static cast as follows:
A *pA = &c;
But, I still get exactly the same error.
Is there any solution for this? BTW, the same works fine without error on Windows using Visual C++ compiler.
I know that virtual inheritance solves this but I need a solution to make this work on g++ on Linux without having to use virtual inheritance. Rather than having to use virtual inheritance, is there any way I can instead specify one of the two path and get rid of the ambiguity. Many thanks!
If you can modify C, one possible approach would be to "inject" a dummy base class between it and A:
class A { };
class B : public A {};
class AlmostA : public A {};
class C : public AlmostA, public B {};
int main()
{
C c;
A *pA = static_cast<A*>(static_cast<AlmostA*>(&c));
}
[Live example]
You can even embed the dual static casts into a function in C.
Long story short, inherit from A virtually to avoid having two distinct As being a part of C:
class A { };
class B : virtual public A {};
class C : virtual public A, public B {};
Now your code will compile and run correctly.
Unlike "regular" base classes, virtual base classes are inherited only once, regardless of the number of paths that have them. Read this Q&A for a detailed explanation of how they work.

Inherit a class that inherits another class that is already included

I have something like this sample of code:
class A
{
public:
bool ComputeSomething(double &x, double y);
...
};
class B: public A{...}
class C: public A{...}
class D: public B, public C
{
bool FindSomething(const A& a);
...
}
My problem is that in class D the function FindSomethng does not know if A comes from B or C. Is there a way to block A in C so that the methods in C from A to be used just in C and in D to use the methods of A from B? I know this is kind od a stupid question. I need to make this to work just by modifying class C because class B and D are to developed to support such changings...
I suggest that you read this FAQ on virtual/multiple inheritance.
In C++, if you have multiple inheritance, either it is non-virtual in which case you get multiple copies of common base classes, or it is virtual in which case there is just one copy of common base classes.
In most cases it is simply better to avoid multiple inheritance.

Check if the type comes from a given parent type

Simplifed example of my problem :
I have an abstract class A. I have two abstract classes B and C inheriting from A. And I have a lot of final classes inheriting from B or C :
class A;
class B : public A;
class C : public A;
class B1 : public B;
class B2 : public B;
class C1 : public C;
class C2 : public C;
I implement an algorithm recieving a pointer of A having to know if the type comes from B or C to work properly :
void algorithm(boost::shared_ptr<const A> a)
{
if(*a is a B instance)
// do something
else if(*a is a C instance)
// do something other
}
How can I check that simply without C++11 ?
I know how to check the final type with typeid(*a) == typeid(C1), but I don't know how to check a parent type...
You can use dynamic_pointer_cast:
if (std::dynamic_pointer_cast<B>(a)) {
...
}
else if (std::dynamic_pointer_cast<C>(a) {
...
}
Use dynamic_cast.
if (dynamic_cast<B *>(a))
{
// // a actually points at a B, or something derived unambiguously from B
}
Of course, more generally, you need to revisit the design of your function. More often than not, it would be better that it not need to know about classes derived from A. Avoiding that usually means using A as a polymorphic base that provides an interface to all functionality needed in the function (e.g. set of virtual functions that classes like B and C might specialise for themselves).

Refer base class members from derived class

class A {
public:
void fa() {
}
};
class B : public A{
public:
void fb() {
}
};
class C : public A, public B {
public:
void fc() {
//call A::fa(), not B::A::fa();
}
};
How to call A::fa() from C::fc() function.
GCC warns withdirect base A inaccessible in C due to ambiguity, does this mean there is no direct way to refer base class members?
One option would be to create a stub class that you can use for casting to the right base class subobject:
struct A {
void fa() { }
};
struct B : A {
void fb() { }
};
// Use a stub class that we can cast through:
struct A_ : A { };
struct C : A_, B {
void fc() {
implicit_cast<A_&>(*this).fa();
}
};
Where implicit_cast is defined as:
template <typename T> struct identity { typedef T type; }
template <typename T>
T implicit_cast(typename identity<T>::type& x) { return x; }
I just found the following info from ISO C++ 2003 standard (10.1.3)
A class shall not be specified as a direct base class of a derived class more than once. [Note: a class can be
an indirect base class more than once and can be a direct and an indirect base class. There are limited
things that can be done with such a class. The non-static data members and member functions of the direct
base class cannot be referred to in the scope of the derived class. However, the static members, enumerations
and types can be unambiguously referred to.
It means there is no direct way :(
I just compiled you code on codepad.org , putting A::fa() is enough to call fa() from your C::fc() function.
void fc() {
A::fa();
}
The below is the link to codepad with your code.
http://codepad.org/NMFTFRnt
I don't think you can do what you want. There is an ambiguity here: when you say A::fa(), it still doesn't tell the compiler which A object to use. There isn't any way to access class A. That's what the warning is telling you.
This seems like an awfully strange construct, though. Public inheritance should be used for is-a relationships. You are saying that C is-a A twice over? It doesn't make sense. And that suggests that this is either an artificial example that would never come up in practice, or you should reconsider this design.
You can use virtual inheritance to overcome such problem:
class B : virtual public A {
Now, you can use A::fa() simply in the child class C.
void fc()
{
fa();
}
However, I generally don't see any practical need to inherit class A again into class C, when B is already publically inheriting A. So, In your case, you can make it simple:
class C : public B {
Edit:
If you want 2 instances for A. then the direct instance which you are intending can be made as an object of C:
class C : public B {
A obj;
Because, having a directly inherited A will not be usable in anyway. You cannot declare any pointer or reference to it inside the scope of C.