C++ pure virtual function implementation upon instantiating object - c++

I'm not sure if this has already been answered somewhere or if what I'm asking is feasible. I'm not so familiar with C++ and OOP in general so forgive me if I'm asking something too obvious, as my mind is a bit stuck right now.
Anyway, what I want to deal with is:
I'm using a framework that handles some callbacks from an app. The API has a class for these events and the callback function as pure virtual function. For example:
class A {
public:
A(){};
~A(){};
virtual void myCallback(){} = 0
};
In my code I'm implementing this callback and I have something like:
class B : A {
public:
B(){
std::cout<<"I'm a ClassB object";
};
~B(){};
void myCallback(){
std::cout<<"Hello callback";
};
};
Now in my main suppose that I'm having something like that:
int main(){
int x=1;
B objB;
//Do some stuff for a while
return 1;
}
I can see upon instantiating the B object the "I'm a ClassB object" message and I can see upon firing the event the "Hello callback" message.
So what I'm asking here is how I can get inside my callback the value of "x" coming from main ? Can I re-implement the callback inside the main somehow? Do you think that my approach on this is correct ?
What I want is to implement pure virtual callback function inside my main by having an object of class B. Or even to somehow get the value of x inside the myCallback function.
I'm not sure if I'm clear enough or if I messed anything up

If I understand the question, what you want is usually called a closure. You want myCallback to know the value of x inside main. There are several ways of doing this, the most straightforward will look something like following:
class B : public A {
public:
B(int x) x(x) {
std::cout<<"I'm a ClassB object";
}
~B() = default;
void myCallback() {
std::cout << "Hello callback, x is " << x << "\n";
}
private:
int x;
};
int main() {
int x = 1;
B objB(x);
//Do some stuff for a while
return 0;
}

Related

Pass parent class reference as argument in derived class in C++

I'm new to C++ and am trying to achieve the following design.
class A { do (); doMore (); } // abstract
class B { do (); doMore (); } // abstract
class X : public A, public B // Also abstract
{
foo() {
// common code
A::do();
A::doMore();
}
bar() {
// common code
B::do();
B::doMore();
}
}
Both A and B provide implementations of do() and doMore().
How can I extract the common code that the new function takes an arg that calls the method in the correct parent class?
Something like
X::newMethod(arg_that_indicates_parent_class) {
// common code
arg_that_indicates_parent_class::do();
arg_that_indicates_parent_class::doMore();
}
Then call it like so
newMethod(pass_A_somehow);
newMethod(pass_B_somehow);
Looks like runtime polymorphism, but not quite (or is it?)... as it is within a child class...
Is this design itself just trash and there is a better way to achieve this?
If the idea is that do and doMore will be present in both A and B and those are the functions specifically you wish to call, you could
use a template function like so:
class X : public A, public B // Also abstract
{
template <typename T>
void newMethod()
{
T::do();
T::doMore();
}
}
Then using it explicitly, you could then do it like so:
X x;
x.newMethod<A>();
x.newMethod<B>();
This has the added benefit of catching some errors at compile time, that is, if you try and pass a C and it does not have
the do and doMore functions defined, you will receive a complier error (instead of a run-time crash).
This also lets you utilize the std::enable_if functionality if you are using C++1x.
Hope that can help.
Just factor out the "common code", and make it, well, common:
class X : public A, public B // Also abstract
{
void foo() {
commoncode();
A::do();
A::doMore();
}
void bar() {
commoncode();
B::do();
B::doMore();
}
void commoncode()
{
// Your common code
}
}
That's the most simple, straightforward way. Another alternative way would be closer in line to your "pass me a pointer of some kind" intended approach:
class X : public A, public B // Also abstract
{
void call_a()
A::do();
A::doMore();
}
void call_b()
B::do();
B::doMore();
}
void commoncode( void (X::*ptr)() )
{
// Your common code
(this->*ptr)();
}
}
And the parameter to commoncode() would be either
&X::call_a
or
&X::call_b

Why can I call instance functions statically?

I was looking around the Notepad++ source code on GitHub recently, and came across a method call like this:
Window::init(hInst, parent);
I searched for the function it was referencing to, and came across a Window class- but the init function was marked virtual, so clearly it was non-static. Thinking I made a mistake, I checked the entire header to make sure there was no static overload of init, and I made sure there was no Window.cpp file. There isn't.
After poking around the source for 15 more minutes, I gave in and git cloned the repo locally so I could open it in Visual Studio. The first thing I did was to build just to make sure this wasn't an accidental merge on behalf of the project developers- the build succeeded.
The next steps I took:
I opened the the file calling Window::init and clicked Go To Declaration on Window. It takes me to the Window class.
I clicked Go To Declaration on the init function. It points me to the signature of the virtual method.
I copy and paste the Window.h file into an entirely new header and replace all references of Window with Foo. When I type in Foo::init, the compiler complains that 'a nonstatic member reference must be relative to a specific object'.
TL;DR: Somehow, the Notepad++ source code calls a non-static method statically, and this builds. Doesn't work with any other class. Proof here and here.
I have spent 2 hours staring at this, but I still don't see how it's possible. Am I missing something?
No, it's not calling a static function. It's just calling the base class's version of init(). Basically, in tClassName::f, you are asking "I want to call that specific version of the virtual function f() in class tClassName".
Generally, it's pretty common to call the base class's counterpart of a virtual function in the derived class. E.g., the factory method pattern:
#include "tObject.h"
#include "tObject1.h" // public inheritance from tObject
#include "tObject2.h" // public inheritance from tObject
#include "tObject3.h" // public inheritance from tObject
class BaseFactory
{
public:
// factory method
virtual tNode *createObject(int id)
{
if (id == 1) return new tObject1;
else return new tObject2;
}
};
class DerivedFactory: public BaseFactory
{
public:
virtual tNode *createObject(int id)
{
// Overrides the default behavior only for one type
if (id == 1) return new tObject3;
// Call the default factory method for all other types
else return BaseFactory::createObject(id);
}
};
Am I missing something?
Yes - context. Notepad_plus_Window derives from Window, and the call to Window::init() is inside of the Notepad_plus_Window::init() method:
class Notepad_plus_Window : public Window {
public:
...
void init(HINSTANCE, HWND, const TCHAR *cmdLine, CmdLineParams *cmdLineParams);
...
};
void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLine, CmdLineParams *cmdLineParams)
{
...
Window::init(hInst, parent);
...
}
In this context, Notepad_plus_Window is calling the base class Window version of init().
Maybe this will confuse you less. You're missing context, at no real fault of your own.
You're not seeing the implicit this in the call.
Take the following example:
#include <cstdio>
#include <iostream>
class Foo {
public:
virtual void bar() {
std::cout << "Foo" << std::endl;
}
};
class Bar : public Foo {
public:
virtual void bar() {
std::cout << "Bar" << std::endl;
}
};
int main() {
Bar bar;
bar.bar(); //-> bar
bar.Foo::bar(); //-> foo
Bar *barp = &bar;
barp->bar(); //-> bar
barp->Foo::bar(); //-> foo
return 0;
}
In the above, we can specify the object on which to call a specific method in the class' hierarchy.
It's not a static function. It's calling a function with a specified (class) scope.
By default, init() will match functions within current class scope, if they do exist. that is an implicit this call, equals this->init(),
But with a specified class/namespace prefix, you can explicit call any particular function without dynamic binding. i.e. ::init() will call the init() function within global scope.
the following code may give you a better understanding
#include <iostream>
class A
{
public:
virtual void test()
{
std::cout << "A" << std::endl;
}
};
class B : public A
{
public:
virtual void test()
{
std::cout << "B" << std::endl;
}
};
int main()
{
A* a = new B();
a->A::test();
return 0;
}

c++ overriding a function only for a specific instance

I was wondering whether there's a way to override a function for a specific instance only. For ex,
class A
{
public:
...
void update();
...
}
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new A();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new A();
// ....so on.
...
}
Is there a way to achieve this?
I think virtual function is just what you want, with virtual function, different instances of the same type can have different functions, but you need to inherit the base class. for example
class A
{
public:
...
virtual void update()
{
std::cout << "Class A\n";
}
...
};
class B: public A
{
public:
virtual void update()
{
std::cout << "Class B\n";
}
};
class C: public A
{
public:
virtual void update()
{
std::cout << "Class C\n";
}
};
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new B();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new C();
// ....so on.
...
}
each instance in the above code will bind different update functions.
Besides, you can also use function pointer to implement your requirement, but it is not recommended. For example
class A
{
public:
A(void(*u)())
{
this->update = u;
}
...
void (*update)();
};
void a_update()
{
std::cout << "update A\n";
}
void b_update()
{
std::cout << "update B\n";
}
void c_update()
{
std::cout << "update C\n";
}
int main()
{
...
A first_instance(a_update);
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A second_instance(b_update);
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A third_instance(c_update);
// ....so on.
...
}
Hope helps!
Hold a function in the class.
#include <iostream>
#include <functional>
using namespace std;
class Foo
{
public:
Foo(const function<void ()>& f) : func(f)
{
}
void callFunc()
{
func();
}
private:
function<void ()> func;
};
void printFoo() { cout<<"foo"<<endl; }
void printBar() { cout<<"bar"<<endl; }
int main()
{
Foo a(printFoo);
Foo b(printBar);
a.callFunc();
b.callFunc();
}
You may have noticed that the end brace of a class is often followed by a semicolon, whereas the end braces of functions, while loops etc don't. There's a reason for this, which relates to a feature of struct in C. Because a class is almost identical to a struct, this feature exists for C++ classes too.
Basically, a struct in C may declare a named instance instead of (or as well as) a named "type" (scare quotes because a struct type in C isn't a valid type name in itself). A C++ class can therefore do the same thing, though AFAIK there may be severe limitations on what else that class can do.
I'm not in a position to check at the moment, and it's certainly not something I remember using, but that may mean you can declare a named class instance inheriting from a base class without giving it a class name. There will still be a derived type, but it will be anonymous.
If valid at all, it should look something like...
class : public baseclass // note - no derived class name
{
public:
virtual funcname ()
{
...
}
} instancename;
Personally, even if this is valid, I'd avoid using it for a number of reasons. For example, the lack of a class name means that it's not possible to define member functions separately. That means that the whole class declaration and definition must go where you want the instance declared - a lot of clutter to drop in the middle of a function, or even in a list of global variables.
With no class name, there's presumably no way to declare a constructor or destructor. And if you have non-default constructors from the base class, AFAIK there's no way to specify constructor parameters with this.
And as I said, I haven't checked this - that syntax may well be illegal as well as ugly.
Some more practical approaches to varying behaviour per-instance include...
Using dependency injection - e.g. providing a function pointer or class instance (or lambda) for some part of the behavior as a constructor parameter.
Using a template class - effectively compile-time dependency injection, with the dependency provided as a function parameter to the template.
I think it will be the best if you'll tell us why do you need to override a function for a specific instance.
But here's another approach: Strategy pattern.
Your class need a member that represent some behaviour. So you're creating some abstract class that will be an interface for different behaviours, then you'll implement different behaviours in subclasses of that abstract class. So you can choose those behaviours for any object at any time.
class A;//forward declaration
class Updater
{
public:
virtual ~Updater() {};//don't forget about virtual destructor, though it's not needed in this case of class containing only one function
virtual void update(A&) = 0;
}
class SomeUpdater
{
public:
virtual void update(A & a);//concrete realisation of an update() method
}
class A
{
private:
Updater mUpdater;
public:
explicit A(Updater updater);//constructor takes an updater, let's pretend we want to choose a behaviour once for a lifetime of an object - at creation
void update()
{
mUpdater.update(this);
}
}
You can use local classes, yet, personally, I consider the "hold function in the class" approach mentioned in the other answer better. I'd recommend the following approach only if doFunc must access internals of your base class, which is not possible from a function held in a member variable:
class ABase {
public:
void Func () { this->doFunc (); }
private:
virtual void doFunc () = 0;
public:
virtual ~ABase () { }
};
ABase* makeFirstA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "First A"; }
};
return new MyA;
}
ABase* makeSecondA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "Second A"; }
};
return new MyA;
}
int main () {
std::shared_ptr<ABase> first (makeFirstA ());
std::shared_ptr<ABase> second (makeSecondA ());
first->Func ();
second->Func ();
}
From a design patterns point of view, the "local classes" approach implements the template method pattern, while the "hold a function(al) in a member variable" approach reflects the strategy pattern. Which one is more appropriate depends on what you need to achieve.

C++ casting and typeid

I got a function that have two base class pointers and depending on the subclass, other functions should be called...
Like this:
void function(A* a, A* a2){
if (typeid(*a).name() == "B"){
if(typeid(*a2).name() == "C"){
otherFunction();
}
if(typeid(*a2).name() == "D"){
otherFunction2();
}
}
}
However, there's a whole buncha problems:
1) I've read that typeid.name yield different result depending on the compiler and therefore I don't want to use it.
2) I've considered creating an instance of "B" and instead writing if(typeid(*a2) == typeid(instanceOfB)) but that would be a lot of work since there are plenty of constructor arguments...
3) I've also considered using dynamic_cast but some subclasses look like this:
A <-- B <-- C
so if if I wanted to check if the argument is B with dynamic cast, it would pass even if the argument is in fact C because C inherits from B
Edit: It seems I'll have to reconsider the design but since many have stated the design is flawed I'll quickly explain what my train of thought:
There's a window. Several different objects are located inside the window and move around, a game. This function was supposed to function as a collision detection. Like this:
Go through all objects on the screen, check if the have collided. Take the two collided objects as arguments and call this function.
This function looks up a buncha different collisions like "if a is "an arrow" and a2 is "a bandit" then do some stuff but if a2 is "a tree" instead, do this instead!
Wouldn't it be better to have some virtual methods in A that do nothing by default and are overwritten by some of its inheriting classes?
class A {
public:
virtual void method(A *a2) {
}
virtual void otherMethod() {
}
};
class B : public A {
public:
virtual void method(A *a2) {
a2->otherMethod();
}
};
class C : public B {
public:
virtual void otherMethod() {
// do your C stuff here
}
};
class D : public A {
public:
virtual void otherMethod() {
// do your D stuff here
}
};
Would this achieve the things you are trying to do?

polymorphism and encapsulation of classes

I'm trying to take advantage of the polymorphism in c++, but I'm from a c world, and I think what I've done could be done more cleverly in a OOP way.
I have 2 classes that has exactly the same public attributes, and I want to "hide" that there exists 2 different implementations. Such that I can have a single class where I can use the member functions as If i were accessing the specific class.
An very simple implementation of what I'm trying to accomplish is below:
#include <iostream>
class subber{
private:
int id;
public:
int doStuff(int a,int b) {return a-b;};
};
class adder{
private:
int id;
public:
int doStuff(int a, int b) {return a+b;};
};
class wrapper{
private:
int type_m;
adder cls1;
subber cls2;
public:
wrapper(int type) {type_m=type;};//constructor
int doStuff(int a, int b) {if(type_m==0) return cls1.doStuff(a,b); else return cls2.doStuff(a,b);};
};
int main(){
wrapper class1(0);
std::cout <<class1.doStuff(1,3) <<std::endl;
wrapper class2(1);
std::cout <<class2.doStuff(1,3) <<std::endl;
return 0;
}
I have 2 classes called "subber" and "adder" which both have a member function called doStuff, which will either subtract of add 2 numbers.
This I wrap up in a class "wrapper", which has both "adder" and "subber" as private variables, and a doStuff public member function. And given which value I instantiate my "wrapper" class with, my "wrapper" class will simply relay the "doStuff" to the correct class.
This code does of cause work, but I would like to avoid instatiating both "subber" and "adder" in my wrapper class, since I will only need of them in each of my "wrapper" classes.
Thanks
There are many ways to do it. Through a Factory for example.
But to keep it simple - make a base abstract class that defines the interface, and derive your classes from it to implement the functionality. Then you only need to make the distinction once, when you create the class, after that you don't care, you just call the interface functions.
your code would look something like that.
class DoStuffer
{
public:
virtual int doStuff(int, int)=0;
virtual ~DoStuffer(){}; // Because Tony insists:-) See the comments
}
class subber: public DoStuffer{
public:
virtual int doStuff(int a,int b) {return a-b;};
};
class adder: public DoStuffer{
public:
virtual int doStuff(int a, int b) {return a+b;};
};
int main(){
DoStuffer *class1 = new adder();
DoStuffer *class2 = new subber();
std::cout <<class1->doStuff(1,3) <<std::endl;
std::cout <<class2->doStuff(1,3) <<std::endl;
delete class1; // don't forget these:-)
delete class2;
return 0;
}
This is one of the more idiomatic ways to use the C++ class system to accomplish what you want. Both adder and subber publicly inherit from wrapper, which is now an abstract base class. The doStuff method is now a (pure) virtual function. And instead of being a simple instance of wrapper, the "encapsulated" object is now a reference to a wrapper.
#include <iostream>
class wrapper {
public:
virtual int doStuff(int a, int b) = 0;
};
class subber : public wrapper {
public:
virtual int doStuff(int a,int b) {return a - b;}
};
class adder : public wrapper {
public:
virtual int doStuff(int a, int b) {return a + b;}
};
int main(){
// actual objects
adder impl1;
subber impl2;
// in real code, the wrapper references would probably be function arguments
wrapper& class1 = impl1;
std::cout << class1.doStuff(1,3) << std::endl;
wrapper& class2 = impl2;
std::cout << class2.doStuff(1,3) << std::endl;
return 0;
}
(Not using any factory pattern in this example, since it's not obvious that it's needed or what the question is about.)
Exactly what was last said.
Make a base class, and have a virtual function |doStuff| in it.
Then you can derive any number of classes out from it, all have to implement the above virtual function, in whatever way they want to.
Then you can just do the following
BaseClass *object1 = new DerivedClass1();
BaseClass *object2 = new DerivedClass2();
..
You can even do
object1 = object2;
And then they point to the same object (i.e. an object of type |DerivedClass2|)
But remember, when you do objectn->doStuff(), the function that will be executed will be what the pointer points to at run-time, and not at compile time.
i.e. if I do object1->doStuff() DerivedClass2's doStuff will be called because we already did `object1 = object2;
You may want to Google and read about
Polymorphism/ Run-time Polymorphism
Virtual Functions in C++
You can read Factory Method, which is something that is known as a Design Pattern, but later in life.
Thanks
The classic run-time polymorphic approach is:
struct Operation
{
virtual ~Operation() { } // guideline: if there are any virtual functions,
// provide virtual destructor
virtual int doStuff(int, int) const;
};
struct Subber : Operation
{
int doStuff(int a, int b) const { return a - b; }
};
struct Adder : Operation
{
int doStuff(int a, int b) const { return a + b; }
};
enum Operations { Add, Subtract };
struct Operation* op_factory(Operations op)
{
if (op == Add) return new Adder;
if (op == Subtract) return new Subber;
throw std::runtime_error("unsupported op");
}
int main()
{
Operation* p1 = op_factory(Add);
std::cout << p1->doStuff(1,3) <<std::endl;
Operation* p2 = op_factory(Subtract);
std::cout << p2->doStuff(1,3) <<std::endl;
delete p1;
delete p2;
}
From the Standard 5.3.5/5 "In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor or the behavior is undefined.", which is why you must use the virtual keyword on the base class destructor.
It's noteworthy that in your example the type of operation to perform was communicated to the wrapper class using a function argument of 0 or 1... this is what suggests you want run-time polymorphism. For example, if the 0 or 1 value was based on a command line argument, file content, keyboard input etc., then the factory method above can pass a corresponding Add or Subtract value and receive an appropriately-behaving object derived from Operation. This concept of creating an instance of a run-time polymorphic type based on run-time values is known as a factory.
If you really only need compile-time polymorphism, you can do some interesting things with templates such as:
template <class Operation>
void output(int a, int b)
{
std::cout << Operation::doStuff(a, b) << std::endl;
std::cout << Operation::doStuff(a * 10, b * 10) << std::endl;
std::cout << Operation::doStuff(a * 100, b * 100) << std::endl;
}
int main()
{
output<adder>(1, 3);
output<subber>(1, 3);
}
FWIW, your approach is probably slightly faster than the virtual function approach (as it can potentially do more inlining), but not as clean, extensible, maintainable or scalable.
I think what you're looking for is virtual functions. If you declare a function virtual in your base class, you can do things like make a vector containing multiple objects derived from your base class, but when you call on a particular object it will execute it's own method.