Is it possible to get the following behavior out of a Union?
class A : public Base //Base is an abstract base class.
{
public:
A( int );
virtual void foo() //A virtual function from Base.
{
//I don't want to have to specify if it's oneOption or twoOption.
// I would like it to just call whichever one's is defined in mData.
mData.foo();
}
private:
union B
{
C oneOption; //A class which inherits from Base.
D twoOption; //Another class which inherits from Base.
} mData;
};
Basically, I would like to have a class containing a Union of derived classes. Then I would like to implement all the virtual functions base class in terms of my Union.
I can try to rephrase this if it's too confusing.
Thanks
Members of a union are not allowed to have constructors.
You can do something like this:
void PickC() { new (oneOption) C; }
void PickD() { new (twoOption) D; }
C * GetC() { return (C*) oneOption; }
D * GetD() { return (D*) twoOption; }
private:
union B
{
char oneOption[ sizeof(C) ]; //A class which inherits from Base.
char twoOption[ sizeof(D) ]; //Another class which inherits from Base.
} mData;
But it is seriously ugly.
Technically you can, the syntax is correct and the compiler will let you treat both instance variables as you'd expect (with the same constraints that applies in general to unions).
In practice it seems unnecessary when there is mutual exclusion, you can easily use a pointer to an instance:
CommonAncestor *mData;
I can see many maintainability issues by using constructs that were meant to be used when polymorphism didn't exist in the language.
Related
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
I have a super Class (A) and two sub Class (B ,C)
an abstract Function in A have two difference return type in B and C!
How i have to Declare these??
return type is important
class A { //Super Class
public:
A();
virtual (some Type) QWERTY() = 0;
};
class B : public A { //Sub Class
public:
B();
double QWERTY();
};
class C : public A { //Sub Class
public:
C();
unsigned int QWERTY();
};
i'v to call sub Class function with super Class pointer
Since the functions are different in each sub-classes, you'll have to access them from pointers to those sub-classes.
This is exactly the kind of situation where dynamic_cast<> can help: it can conditionally convert a pointer from a base class to a sub-class if and only if it happens to be of the correct type:
void foo(A* a_ptr) {
B* b_ptr = dynamic_cast<B*>(a_ptr);
C* c_ptr = dynamic_cast<C*>(a_ptr);
if(b_ptr) {
b_ptr->QWERTY();
}
if(c_ptr) {
c_ptr->QWERTY();
}
}
It's, however, worth mentioning that this is some pretty ugly code, and might be suitable to solve the quiz you are presenting us, but in a normal environment, there are some design reevaluation that would happen before going to implement things this way.
Static code analysis tools tend to ramble a lot about "downcasting a base class to a derived class" and I also found a couple of coding standard guides, which mention not to do this so I was wondering what is the best-practice way.
Here's my use case:
I have a Base (interface), DerivedA, DerivedB classes and then an array containing Base pointers.
Then I iterate through the array and based on a flag, I determine if the object is DerivedA or DerivedB, cast it down and do some random stuff to the object from the outside.
Basically something like this:
// arr is of type Base**
for (int i = 0; i < size; ++i)
{
// doMagic has an overload for both types
if (arr[i]->isDerivedA())
{
doMagic(reinterpret_cast<DerivedA*>(arr[i]));
}
else if (arr[i]->isDerivedB())
{
doMagic(reinterpret_cast<DerivedB*>(arr[i]));
}
}
Bout the reinterpret, I cannot use dynamic_cast due to embedded platform restrictions (the same for C++11), but the Base class being an interface guarantees that the object is either DerivedA or DerivedB.
I could make DerivedA and DerivedB only implement pure virtual calls, thus i wouldn't have to worry about downcasting anything, but the DerivedA and DerivedB classes are very much specialized and doMagic does completely different things with the instances...
So I was wondering how you guys approach this - having a single array of very different objects, but inherited from a single base, iterating through them and doing some specialized stuff from the outside.
You probably should try to use visitor pattern.
Here is a simple example:
#include <cstdio>
class A;
class B;
class Visitor {
public:
void visit(A &a) {
printf("Visited A\n");
}
void visit(B &) {
printf("Visited B\n");
}
};
class A {
public:
virtual ~A() { }
virtual void applyVisitor(Visitor &v) {
v.visit(*this);
}
};
class B : public A {
public:
~B() override { }
void applyVisitor(Visitor &v) override {
v.visit(*this);
}
};
int main() {
A a;
B b;
Visitor v;
a.applyVisitor(v);
b.applyVisitor(v);
return 0;
}
If you know that a pointer of a base class points to an object of a derived class, you may use static_cast. The compiler will insert appropriate code to adjust offsets, unlike reinterpret_cast or a C-Cast.
I'm trying to properly encapsulate a class A, which should only be operated on by class B.
However, I want to inherit from class B.
Having A friend B doesn't work -- friendship isn't inherited.
What's the generally accepted way of accomplish what I want, or am I making a mistake?
To give you a bit more color, class A represents a complex system's state. It should only be modified by B, which are actions that can be applied to change class A's state.
It sounds like you may need to do a redesign; your class A represents a State, but your Class B represents a set of actions. There's a relationship there, but it's not an inheritance relationship. I'd suggest composition; you want more of a HASA relationship than an ISA relationship, as far as I can tell.
I assume you want to allow descendants of B to access A directly? If A and B are tightly coupled, you can make A a protected class definition within B itself, instead of being an independent definition. E.G.
class B
{
protected:
class A
{
};
};
Another idea is to create protected methods on B that delegate their actions to A. E.G.
class A
{
friend class B;
private:
void DoSomething();
};
class B
{
protected:
void DoSomething(A& a) { a.DoSomething(); }
};
If I understand you correctly, you want to have B and it's derivatives to have access to the internal implementation of class A, yes?
Unfortunately, C++ does not have the concept of "internal" protection levels that languages like C# and Java posses.
You can consider using the private implementation paradigm (pimpl) - also known as opaque pointers, to expose functionality within your system using public access levels, that consumers of A and B would not see.
Keeping everything as is, the easiest thing to do is to add protected methods to B that give access to the equivalent feature of A it would need. This opens the encapsulation to just subclasses of B.
The most straightforward way to do this is simply to have B contain an A:
class B {
protected:
A a_;
};
Then, you can write a class C which inherits from B and is able to manipulate A. If C shouldn't be able to do arbitrary things to the A, then make the A private in B and provide protected methods in B that C can use to do approved things to the A, like so:
class B {
private:
A a_;
protected:
void doSomethingToA();
};
Containment is the way to go (class B contains private member of type A) unless B needs to override some virtuals in A, in which case private inheritance is the closest thing.
I cant see why you would want to inherit. Make everything in A private and friend B. B then has a member of A which it can freely manipulate.
The way you describe this it sounds more like composition rather than inheritance. E.g.
class ComplexMachine {
public:
setState(int state);
};
class Operator {
public:
Operator(ComplexMachine & m) :_m(m) {};
void drive() { _m->setState(1); }
void turn() { _m->setState(2); }
void stop() { _m->setState(0); }
private:
ComplexMachine _m;
};
class SmoothOperator : public Operator { }
Working with the bits of information you have given:
Class B should be responsible for preserving the invariants of class A, and class B should be the only way to manipulate A. Any client - derived class or caller - should not need to know that A exists.
(From design POV, there's even no need for A to exist, but I have encountered enough practical reasons for such a separation that I won't hold it against you ;))
This might require a lot of boilerplate code to be written, or some trickery with the interface. e.g. if client should be allowed to use class A to query information but not to modify it, B could hand out a const & to the aggregated A. With a compiler supporting __declspec(property) or similar, the syntactic pain can be eased.
If you want to be sure that only B operates on A, make the instance of A private and expose a protected interface from B to its descendants.
class A
{
public:
void foo() {}
};
class B
{
private:
A a;
protected:
void CallAFoo() { a.foo() };
};
class C : public B
{
void goo() { CallAFoo(); }
};
From what I understand from your question, you will need some polymorphism. You need an abstract class A and class B inherits class A. Also, the protected keyword allows the classes that inherit to have access to certain information while at the same time deny access to anything else. Here is a little example:
// dynamic allocation and polymorphism
#include <iostream>
using namespace std;
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) =0;
void printarea (void)
{ cout << this->area() << endl; }
};
class CRectangle: public CPolygon {
public:
int area (void)
{ return (width * height); }
};
class CTriangle: public CPolygon {
public:
int area (void)
{ return (width * height / 2); }
};
int main () {
CPolygon * ppoly1 = new CRectangle;
CPolygon * ppoly2 = new CTriangle;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly1->printarea();
ppoly2->printarea();
delete ppoly1;
delete ppoly2;
return 0;
}
Code taken from cplusplus.com (contains information on polymorphism and abstract classes too).
I just cannot imaginate a way to do a call to a function with genericity. I have a code which a have to call a function in two different classes in different moments.
I have A and B classes which I can access one time or other time. Or I access A or I access B. Not both in the same type.
I have code this program but I just cannot imagine how to do this. Or if this is good for performance or codding. I just want to eliminate the C class but I don't know how.
Any idea?
class MyClass
{
public:
MyClass() {} //contructor padrão, não deve ser utilizado isoladamente
virtual int a() = 0;
virtual int b() = 0;
int c()
{
return b();
}
};
class A : public MyClass
{
public:
int a() { return 1; }
int b() { return 1; }
int d() { return 1; }
};
class B : public MyClass
{
public:
int a() { return 1; }
int b() { return 1; }
int e() { return 1; }
};
class C
{
public:
A ca;
B cb;
enum TIPO { A, B };
TIPO Tipo;
C(TIPO tipo) { Tipo = tipo; }
int a()
{
switch(Tipo)
{
case A:
return ca.a();
break;
case B:
return cb.b();
break;
default:
break;
}
}
};
void main()
{
C c(C::B);
c.a();
return;
}
If I understand you correctly, you are trying to eliminate the members (ca,cb), and just call the appropriate base class method.
If that's the case, it can be done by using:
switch(Tipo) {
case A:
return A::a();
case B:
return B::a();
}
However, I would recommend revisiting your design. Typically, situations like this can often be handled by rethinking/reworking the class design so that there is a single base class or interface which defines a(), and instead of creating one concrete class with 2 base classes, create one of two specific, concrete classes derived from a single base class. There is no need for multiple inheritance here. (This is especially true since you know the type at construction time.)
As you've written 'A' and 'B', you don't actually need the C class. By declaring your member functions "virtual" you are using run time polymorphism and this will result in the "correct" functions being called:
void foo (MyClass & mc) {
mc.a ();
}
int main () {
A a;
B b;
foo (a); // 'mc.a()' will call 'A::a'
foo (b); // 'mc.a()' will call 'B::a'
}
Is there some other reason that you need to inherit from C?
First of all, decide if your A and B classes will belong to C by inheritance or by composition. Right now you're doing both, which is both bloating your code and making it confusing.
If you do go for inheritance, then you have another problem: similarly named overridden methods, a prime cause for the Deadly Diamond of Death. Multiple inheritance, in case you haven't heard, is evil. Avoid it unless there is no other way to get the job done.
If you go with composition (my recommendation), then it seems to me that your specification of "not at the same time" becomes unnecessary. You're not accessing the same data, so there's no possibility of a race condition. And if you are (for some ungodly reason) determined to access the same memory space, then you'll need to brush up on multithreading, the implementation of which will differ with each platform you develop on.
Ok, I guess you want C::a() to call A::a() or B::b() depending on what "type" or "mode" C has. First of all there is no need to let C inherit A and B.
class C
{
private:
A ca;
B cb;
enum TIPO { A, B };
TIPO Tipo;
public:
SetTipo(TIPO tipo) { Tipo = tipo; }
// ..
};
void main()
{
C c(C::B); // Start with mode B and call B::b()
c.a();
c.SetTipo(C::A); // Now I'm in mode A .. call A::a()
c.a();
return;
}
This assumes that C really should own one instance of A and one instance of B and I'm not sure if that's what you want. Your question didn't state if that's the case or not.
Cheers
This question is very unclear. I have another interpretation of the question, along with an answer.
Interpretation: given:
class C {
public:
int a();
int b();
};
You want to call either method a() or method b(), selectable at runtime. Solution: member function pointers.
A member function pointer is like a regular C function pointer, except that it applies to a method in a class, and its type signature includes the name of the class it's invoked on. Here's how to use one with the class I've just given:
typedef int (C::*SELECT_FUNC)(void);
This is the declaration of the member function pointer. It is similar to the declaration of a regular C function pointer, with the addition of a class name. Now we can assign it:
SELECT_FUNC ptr = &C::a;
SELECT_FUNC other_ptr = &C::b;
And to call:
C item;
C *item_ptr;
int rv = item.*ptr();
int rv2 = item_ptr->*other_ptr;
This syntax is funky. Think of the "*" as "dereference". We are dereferencing the member function pointer to get a METHOD, at which point we can invoke the method in what is otherwise the normal way.
The cool thing about this is: it doesn't even matter if the methods are virtual or not. You can assign either a virtual method or a non-virtual method to a member function pointer. If you call a method through a function pointer and the method happens to be virtual, then you'll get a true virtual call (i.e. if the function pointer is declared to point to a base class method, but you use a derived class instance for "this", then the derived class method will be called, just as it is for a normal virtual call.)
I would think through your requirements carefully. Your question is not well asked, which leads me to believe that you do not understand yourself what you really want to achieve. Once you understand what you want to achieve, then either a class hierarchy or member function pointers (or both) may be the best choice to solve your problem.