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.
Related
I try to have an abstract base class act like an interface and instantiate a derived class based on user input. I tried to implement it like this
class A
{
public:
virtual void print() = 0;
};
class B : A
{
public:
void print() override { cout << "foo"; }
};
class C : A
{
public:
void print() override { cout << "bar"; }
};
int main()
{
bool q = getUserInput();
A a = q ? B() : C();
a.print();
}
But that does not work. I’m coming from c# and that would be valid c# so I’m looking for an equivalent way of implement it in c++. Could someone please give me a hint? Thanks!
There are two problems with the code in its current state.
By default in C++, a class that inherits from a class or struct will be private inheritance. E.g. when you say class B : A, it's the same as writing class B : private A -- which in C++ restricts the visibility of this relationship only to B and A.
This is important because it means that you simply cannot upcast to an A from outside the context of these classes.
You are trying to upcast an object rather than a pointer or reference to an object. This fundamentally cannot work with abstract classes and will yield a compile-error even if the code was well formed.
If the base class weren't abstract, then this would succeed -- but would perform object slicing which prevents the virtual dispatch that you would expect (e.g. it won't behave polymorphically, and any data from the derived class is not present in the base class).
To fix this, you need to change the inheritance to explicitly be public, and you should be using either pointers or references for the dynamic dispatch. For example:
class A
{
public:
virtual void print() = 0;
};
class B : public A
// ^~~~~~
{
public:
void print() override { cout << "foo"; }
};
class C : public A
// ^~~~~~
{
public:
void print() override { cout << "bar"; }
};
To model something closer to the likes of C#, you will want to construct a new object. With the change above to public, it should be possible to use std::unique_ptr (for unique ownership) or std::shared_ptr (for shared ownership).
After this, you can simply do:
int main() {
auto a = std::unique_ptr<A>{nullptr};
auto q = getUserInput();
if (q) { // Note: ternary doesn't work here
a = std::make_unique<B>();
} else {
a = std::make_unique<C>();
}
}
However, note that when owning pointers from an abstract base class, you will always want to have a virtual destructor -- otherwise you may incur a memory leak:
class A {
public:
...
virtual ~A() = default;
};
You can also do something similar with references if you don't want to use heap memory -- at which point the semantics will change a little bit.
References in C++ can only refer to an object that already has a lifetime (e.g. has been constructed), and can't refer to a temporary. This means that you'd have to have instances of B and C to choose from, such as:
int main() {
auto b = B{};
auto c = C{};
bool q = getUserInput();
A& a = q ? b : c;
a.print(); // A& references either 'b' or 'c'
}
You need to use pointers :
A* a = q ? static_cast<A*>(new B) : new C;
...
delete a;
A ternary is also a special case here, as it takes the type of the first expression.
If C inherited from B here it would not be a problem.
Here is the code
,it is my homework using overriden methods teacher told us to analyze the code. I know the code is outputting 2, I have no clue how this code work.
public:
int a;
virtual void who(void) { a = 1; }
};
class B:public A{
public:
int a;
void who(void) { a = 2; }
};
class C :public B {
};
int main(void) {
A x; B y; C z; A *p;
p = &z;
p->who();
cout << z.a << endl;
system("pause");
return 0;
}
B overrides the who() function of its parent, A. This is called polymorphism. C inherits from B, but doesn't override anything; thus, it uses all of the implementation of B.
p is a pointer to an object of class A. One of the key features of class inheritance is that a pointer to a derived class is type-compatible with a pointer to its base class [1].
This means that when you call a member function of a pointer (p->who()), and the class of the object the pointer is pointing to overrides a member of its parent, is going to use the overridden member.
Sources:
[1] http://www.cplusplus.com/doc/tutorial/polymorphism/
as long as you create a function with same input and output with name; in short: same function declaration.. the new one will be used as you refer to one which has super class that has same function. in your case; super class for C is B and it doesn't see A, but B sees A and use all functions it has except what's B declare a new implementation for.
Disclaimer: I'm a long time C programmer moving into C++, so it's very likely/possible there is a better way to do this.
I would like to create a class A with 1 to N members of class B. In most cases, I'm fine calling class B's member functions. However, in some cases I would like to override a member function in class B. Is there an elegant way to do this without having to create a derived class from class B every time?
Here is an example:
using namespace std;
#include <iostream>
class B
{
public:
void print();
};
void B::print()
{
cout << "B::print" << endl;
}
class A
{
public:
B b;
B bprime;
};
int main()
{
A a;
a.b.print();
a.bprime.print();
return 0;
}
Is there a way to override the print() function in bprime or otherwise change it? In C, I would have left class B as a struct and used function pointers, but I'd like to avoid that here.
You can use std::function to simulate polymorphism.
class B
{
public:
std::function<_FUNCTION_SIGNATURE_HERE_> print;
};
then you can always override print member in an instance of B
a.bprime.print = SomeOTherFunctionWithSameSignature;
and from this moment on bprime will behave as if it was a different subclass in a hierarchy. Everything will work the same, except this particular function you changed.
Of course you will have to set initial behavior of print member in your constructor.
I've got a base class that has a virtual function. I want to call that class during the construction because I want the function called for each of the derived classes. I know I can't call a virtual function during construction, but I can't think of an elegant (i.e., avoid repeating code) solution.
What are some work arounds to calling a virtual function during construction?
The reason I want to avoid this is because I don't want to have to create constructors that just call the base class.
class A {
public:
A() {
read();
}
// This never needs to be called
virtual void read() = 0;
}
class B:A {
public:
B():A() { };
read() { /*Do something special for B here.*/ }
}
class C:A {
public:
C():A() { };
read() { /*Do something special for C here.*/ }
}
PS: The Python way of doing this is simply to raise NotImplementedError in A::read(). I'm returning to C++ and I'm more rusty than I thought.
The FAQ perspective.
This is a Frequently Asked Question.
See the C++ FAQ item titled “Okay, but is there a way to simulate that behavior as if dynamic binding worked on the this object within my base class's constructor?”.
It’s very often a good idea to check the FAQ (and generally, googling or altavista’ing) before asking.
The question as “Derived class specific base initialization”.
To be clear, while the literal question above is
“What are some work arounds to calling a virtual function during construction?”
it is evident that what’s meant is
“How can a base class B be designed so that each derived class can specify part of what goes on during B construction?”
A major example is where C style GUI functionality is wrapped by C++ classes. Then a general Widget constructor might need to instantiate an API-level widget which, depending on the most derived class, should be a button widget or a listbox widget or whatever. So the most derived class must somehow influence what goes on up in Widget’s constructor.
In other words, we’re talking about derived class specific base construction.
Marshall Cline called that “Dynamic Binding During Construction”, and it’s problematic in C++ because in C++ the dynamic type of an object during class T construction and destruction, is T. This helps with type safety, in that a virtual member function is not called on a derived class sub-object before that sub-object has been initialized, or its initialization has started. But a major cost is that DBDI (apparently) can’t be done in a way that is both simple and safe.
Where the derived class specific init can be performed.
In the question the derived class specific action is called read. Here I call it derived_action. There are 3 main possibilities for where the derived_action is invoked:
Invoked by instantiation code, called two-phase construction.
This essentially implies the possibility of having a mostly unusuable not fully initialized object at hand, a zombie object. However, with C++11 move semantics that has become more common and accepted (and anyway it can be mitigated to some extent by using factories). A main problem is that during the second phase of construction the ordinary C++ protection against virtual calls on uninitialized sub-objects, due to dynamic type changes during construction, is not present.
Invoked by Derived constructor.
For example, derived_action can be invoked as an argument expression for the Base constructor. A not totally uncommon technique is to use a class template to generate most derived classes that e.g. supply calls of derived_action.
Invoked by Base constructor.
This implies that knowledge of derived_action must be passed up to the constructor, dynamically or statically. A nice way is to use a defaulted constructor argument. This leads to the notion of a parallel class hierarchy, a hierarchy of derived class actions.
This list is in order of increasing sophistication and type safety, and also, to the best of my knowledge, reflects the historical use of the various techniques.
E.g. in Microsoft’s MFC and Borland’s ObjectWindows GUI early 1990’ libraries two-phase construction was common, and that kind of design is now, as of 2014, regarded as very ungood.
This is the factory method approach, putting the factory into the base class:
class A {
public:
virtual void read() = 0;
template<class X> static X* create() {X* r = new X;X->read();return X;}
virtual A* clone() const = 0;
};
class B : public A {
B():A() { };
friend class A;
public:
void read() { /*Do something special for B here.*/ }
B* clone() const {return new B(*this);}
};
class C : public A {
C():A() { };
friend class A;
public:
void read() { /*Do something special for C here.*/ }
C* clone() const {return new C(*this);}
};
Added a clone-method with covariant return type as a bonus.
Using CRTP:
class A {
public:
// This never needs to be called
virtual void read() = 0;
virtual A* clone() const = 0;
};
template<class D, class B> struct CRTP : B {
D* clone() {return new D(*this);}
static D* create() {return new D();}
};
class B : public CRTP<B, A> {
B() { };
public:
void read() { /*Do something special for B here.*/ }
};
class C : public CRTP<C, A> {
C() { };
public:
void read() { /*Do something special for C here.*/ }
};
One way to achieve this, would be simply to delegate it to another class (that is perhaps a friend) and can be sure to be called when fully constructed.
class A
{
friend class C;
private:
C& _c; // this is the actual class!
public:
A(C& c) : _c(c) { };
virtual ~A() { };
virtual void read() = 0;
};
class B : public A
{
public:
B(C& c) : A(c) { };
virtual ~B() { };
virtual void read() {
// actual implementation
};
};
class C
{
private:
std::unique_ptr<A> _a;
public:
C() : _a(new B(*this)) { // looks dangerous? not at this point...
_a->read(); // safe now
};
};
In this example, I just create a B, but how you do that can depend on what you want to achieve and use templates on C if necessary, e.g:
template<typename VIRTUAL>
class C
{
private:
using Ptr = std::unique_ptr<VIRTUAL>;
Ptr _ptr;
public:
C() : _ptr(new VIRTUAL(*this)) {
_ptr->read();
};
}; // eo class C
The workaround is to call the virtual function after construction. You can then couple the two operations (construction + virtual call) in factory function. Here is the basic idea:
class FactoryA
{
public:
A *MakeA() const
{
A *ptr = CreateA();
ptr->read();
return ptr;
}
virtual ~FactoryA() {}
private:
virtual A *CreateA() const = 0;
};
class FactoryB : public FactoryA
{
private:
virtual A *CreateA() const { return new B; }
};
// client code:
void f(FactoryA &factory)
{
A *ptr = factory.MakeA();
}
As mentioned by Benjamin Bannier, you can use CRTP (a template which defines the actual read() function.) One problem with that method is that templates have to always be written inline. That can at times be problematic, especially if you are to write really large functions.
Another way is to pass a function pointer to the constructor. Although, in a way, it is similar to calling the function in your constructor, it forces you to pass a pointer (although in C++ you could always pass nullptr.)
class A
{
public:
A(func_t f)
{
// if(!f) throw ...;
(*f)();
}
};
class B : A
{
public:
B() : A(read) {}
void read() { ... }
};
Obviously, you have the "can't call other virtual functions" problem within the read() function and any function it calls. Plus, variable members of B are NOT yet initialized. That is probably a much worst problem in this case...
For that reason, writing it this way is safer:
B() : A()
{
read();
}
However, in cases like that, that may be the time when you an some for of init() function. That init() function can be implemented in A() (if you make it accessible: i.e. use public A when deriving) and that function can call all the virtual functions as expected:
class A
{
public:
void init()
{
read();
}
};
class B : public A
{
public:
...
};
I know a lot of people say that an init() function is evil because people who create a B object now need to know to call it... but there isn't much else you can do. That being said, you could have a form of factory, and that factory can do the init() call as required.
class B : public A
{
public:
static B *create() { B *b(new B); b->init(); return b; }
private:
B() { ... } // prevent creation without calling create()
};
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.