I'm trying to write a program that calls for a function stored inside a class whose implementation is defined by another object instance.
Let me clarify this better: I would like to create an object A and call for its functions (like an abstract object), but the body of this functions should be defined by either an instance of class B or class C.
I know abstract classes exist in C++ and that i could just call the derived objects, but my goal is to call for object A methods without caring (or knowing in advance) whether an instance of object B or C was previously created.
I tried to use pointers to functions, unfortunately with no results. My code was something like this
Class A:
class A {
public:
static void (*someFunction)();
};
Class B:
class B {
public:
B(){
A::someFunction = someFunction;
}
private:
void someFunction(){
std::cout << "some function" << std::endl;
}
};
Main code:
B b;
A::someFunction();
What am I doing wrong or could be done in a more simple and elegant way? Sorry for the poor explaination and thank you in advance for your help.
Polymorphism exists for just this type of situation, eg:
class A {
public:
virtual ~A() = default;
virtual void someFunction() = 0;
};
class B : public A {
public:
void someFunction() override {
std::cout << "some function" << std::endl;
}
};
class C : public A /* or B*/ {
public:
void someFunction() override {
std::cout << "some other function" << std::endl;
}
};
void doIt(A &a) {
a.someFunction();
}
B b;
doIt(b);
C c;
doIt(c);
Online Demo
But, if that is not what you want, then consider having A use std::function instead of a raw function pointer. Then B and C can assign whatever they want to A::someFunction using lambdas or std::bind(), eg:
A.h:
#include <functional>
class A {
public:
static std::function<void()> someFunction;
};
A.cpp:
#include "A.h"
std::function<void()> A::someFunction;
B.h:
#include "A.h"
class B {
public:
B(){
A::someFunction = [this](){ someFunction(); };
or:
A::someFunction = std::bind(&B::someFunction, this);
}
private:
void someFunction(){
std::cout << "some function" << std::endl;
}
};
C.h:
#include "A.h"
class C {
public:
C(){
A::someFunction = [this](){ someFunction(); };
or:
A::someFunction = std::bind(&C::someFunction, this);
}
private:
void someFunction(){
std::cout << "some other function" << std::endl;
}
};
#include "A.h"
#include "B.h"
#include "C.h"
B b;
A::someFunction();
C c;
A::someFunction();
Online Demo
Related
I would like to hide a virtual method instead of override. I know for historic / compatibility reasons the override specifier is optional and overriding happens implicitly.
To stop overriding I usually adjusted the signature by adding a defaulted "Dummy" parameter. Is there a better way?
Assume this code:
#include <iostream>
class A{
public:
virtual void Foo()
{
std::cout << "A::Foo";
}
};
class B : public A
{
public:
void Foo() /*not override, just hide*/
{
std::cout << "B::Foo";
}
};
int main()
{
B b{};
A& a = b;
a.Foo(); //should print A::Foo - but prints B::Foo
}
What I did so far is this:
#include <iostream>
class A{
public:
virtual void Foo()
{
std::cout << "A::Foo";
}
};
template<typename T>
class reintroduce{};
class B : public A
{
public:
void Foo(reintroduce<B> = {}) /*not override, just hide*/
{
std::cout << "B::Foo";
}
};
int main()
{
B b{};
A& a = b;
a.Foo(); //should print A::Foo
}
The question is not too clear on the requirements of "hiding" but the following effectively "hides" the inherited method in the derived class, while not changing its visibility/accessibility in the base class.
#include <iostream>
class A {
public:
virtual void Foo()
{ std::cout << "A::Foo"; }
};
class B : public A
{
private:
using A::Foo;
};
int main()
{
B b;
b.Foo(); // error, cannot access private member
b.A::Foo(); // ok, calls A::Foo
A& a = b;
a.Foo(); // ok, calls A::Foo
}
#include <iostream>
class A {
protected:
int foo;
};
class B : public A {
public:
B(int bar) { foo = bar; }
int method() { return foo; }
};
class C {
private:
A baz;
public:
C(A faz) { baz = faz; }
A get() { return baz; }
};
int main(void) {
C boo(B(1));
std::cout << boo.get().method() << std::endl;
return 0;
}
I have a base class A which B is a derived class of. Class C takes an A yet I have passed a derived class (B) in its place. No warnings or errors passing a B to C, but I'd like to have method visibility of method() in the above situation.
I'm not very familiar with virtual but I did try to add virtual int method() = 0; to A which lead to further errors.
Consider were I to add a second derived class:
class D : public A {
public:
D(int bar) { foo = bar; }
int method() { return foo+1; }
};
I'd like C to be able to take either B or D and my best assumption would be to take an A and let it handle it.
How do I use polymorphism correctly in this fashion?
Expected output with the below:
int main(void) {
C boo(B(1));
C boz(D(2));
std::cout << boo.get().method() << std::endl;
std::cout << boz.get().method() << std::endl;
return 0;
}
Would be:
1
3
First of all, in order to use A polymorphically, you need to add a virtual destructor, otherwise you will run into undefined behavior when trying to destroy the object. Then the method that you want to call through A must be virtual as well. If it shouldn't have an implementation in the base class itself, make it pure virtual:
class A {
protected:
int foo;
public:
virtual ~A() {}
virtual int method() = 0;
};
Then in C you need to use pointers or references to A, since polymorphism only works with those.
If you want C to own the A, as your code example to suggest, then you need to provide a destructor deleting the pointer and you need to disable copying of the class (or decide on some useful semantics for it):
class C {
private:
C(const C&); // Don't allow copying
C& operator=(const C&); // Don't allow copying
A* baz;
public:
C(A* faz) : baz(faz) { }
~C() { delete baz; }
A& get() { return *baz; }
};
int main(void) {
C boo(new B(1));
C boz(new D(2));
std::cout << boo.get().method() << std::endl;
std::cout << boz.get().method() << std::endl;
return 0;
}
Ideally you would upgrade to C++11 and use std::unique_ptr<A> instead of A* as member. But even if you can't do that, consider using boost::scoped_ptr<A>, which will manage the deletion for you (you don't need the destructor) and will make the class non-copyable by default. It also provides better exception-safety to encapsulate allocations in smart pointers like that.
If you need to call method() of type B using base class type A there has to be lookup during the runtime. The lookup is necessary to answer the question: Which method should be called? - the one that corresponds the type in a current line? Or other method in inheritance hierarchy?" If you expect method() from class B to be called when you have pointer or reference to A then you have to create a lookup table. This table is called vtable (from virtual functions table) and it's defined by adding virtual keyword to functions.
#include <iostream>
class A {
public:
virtual ~A(){}
virtual int method() = 0;
protected:
int foo;
};
class B : public A {
public:
B(int bar) { foo = bar; }
int method() {
std::cout << "Calling method() from B" << std::endl;
return foo; }
};
class C {
private:
A* baz;
public:
C(A* faz) { baz = faz; }
A* get() { return baz; }
};
int main(void) {
A* element = new B(1);
C boo(element);
boo.get()->method();
return 0;
}
It prints "Calling method() from B". Please keep in mind that the code is for presentation purposes and it's not good from best practices perspective.
class A {
void functionA();
};
class B {
A* A_;
void functionB();
};
How can I automatically call functionB() in a class B instance, if functionA() is called outside of the class B instance? (Pointer to a Class A instance is member of the class B instance).
I am looking for something like the SIGNAL/SLOT method in Qt.
One option is to use a function object as a callback. In the following example, B's constructor registers a lambda function in the A instance which will be called by A whenever functionA is called. This lambda, in turn, simply calls functionB.
#include <functional>
#include <iostream>
class A {
public:
void functionA() {
std::cout << "Function A called" << std::endl;
if (callback_) {
callback_();
}
}
void setCallback(std::function<void(void)> callback) {
this->callback_ = callback;
}
private:
std::function<void(void)> callback_;
};
class B {
public:
B(A* a) : A_(a) {
A_->setCallback([this](){this->functionB();});
}
void functionB() {
std::cout << "Function B called" << std::endl;
}
private:
A* A_;
};
int main() {
A a;
B b = B(&a);
a.functionA();
}
The output:
Function A called
Function B called
As you can see in the output, when a.functionA() is called in main, functionB is also called automatically.
I have a little problem with this code :
#include <iostream>
class A {
public:
void PrintA() {
std::cout << "A";
}
};
class B : public A {
public:
void PrintB() {
std::cout << "B";
}
};
int main() {
A a;
a.PrintA();
B b;
b.PrintA();
b.PrintB();
system("PAUSE");
}
Can you tell me if there exist a way to define in A class an object B and use it's methods something like :
class A {
public:
void PrintA() {
std::cout << "A";
}
B bclass;
};
And use in main function something like :
int main() {
A a;
a.bclass->PrintB();
system("PAUSE");
}
The question you need to ask yourself
How does the compiler figure out the size of A
Well - It needs to figure out the size of B
But B has an A in it.
You can go around that loop forever
So you cannot do it.
So use a pointer and forward declaration
Generally functions definition is placed in cpp files and class definition in h or hpp files.
In cpp files you include both hpp with both classes.
Each function defined in cpp have see definition of both classes and may create new one of them.
But in declaration you may only use pointer or reference to object of that class.
== a.hpp ==
#pragma once
class B;
class A {
public:
void PrintA();
B* b;
};
== b.hpp ==
#pragma once
#include "a.hpp"
class B : public A {
public:
void PrintB();
A* a;
};
== a.cpp ==
#include "a.hpp"
#include "b.hpp"
void A::PrintA() {
b = new B();
std::cout << "A";
}
== b.cpp ==
#include "a.hpp"
#include "b.hpp"
void B::PrintB() {
a = new A();
std::cout << "A";
}
And main:
int main() {
A a;
a.PrintA();
a.b->PrintB();
B b;
b.PrintA();
b.PrintB();
system("PAUSE");
}
Worked example available at this link all in one file.
There one else link where seems Visual Studio compiler used.
Just for a sample, you can point to a B instance from an A instance like below, with a pointer:
class A {
public:
void PrintA() {
std::cout << "A";
}
std::unique_ptr<B> bclass;
};
A a;
A.bclass=new B;
A.bclass->PrintB();
The unique pointer will manage memory deallocation.
I have a class structure similar to the following
class A
{
public:
A(void);
~A(void);
void DoSomething(int i)
{
std::cout << "Hello A" << i << std::endl;
}
};
class B : public A
{
public:
B(void);
~B(void);
void DoSomething(int i)
{
std::cout << "Hello B" << i << std::endl;
}
};
class Ad : public A
{
public:
Ad(void);
~Ad(void);
};
class Bd : public B
{
public:
Bd(void);
~Bd(void);
};
I want to store instances of the derived classes in a container (standard map) as a collection of A*, then iterate through the container and call methods for each instance.
#include "A.h"
#include "B.h"
#include "Ad.h"
#include "Bd.h"
#include <map>
int main(int argc, char** argv)
{
std::map<int,A*> objectmap;
objectmap[1] = new Ad();
objectmap[2] = new Bd();
for (std::map<int,A*>::iterator itrobject = objectmap.begin();
itrobject!=objectmap.end(); itrobject++)
{
itrobject->second->DoSomething(1);
}
return 0;
}
The above code produces the following output.
Hello A1
Hello A1
Where I was expecting
Hello A1
Hello B1
because I was expecting DoSomething in B to hide DoSomething in A, and because I am storing A pointers, I would expect no object slicing (and looking at the object pointer in the debugger shows that the object has not been sliced).
I have tried down casting and dynamic casting the pointer to B, but it slices away the data members of Bd.
Is there any way to call B::DoSomething without casting the pointer to Bd? And if not, if I have many derived classes of B (e.g. Bda, Bdb, Bdc etc), is there some way to use RTTI to know which derived class to cast it to?
You need to make DoSomething() a virtual function in both classes to get the polymorphic behavior you're after:
virtual void DoSomething(int i) { ...
You don't need to implement virtual functions in every sub class, as shown in the following example:
#include <iostream>
class A {
public:
virtual void print_me(void) {
std::cout << "I'm A" << std::endl;
}
virtual ~A() {}
};
class B : public A {
public:
virtual void print_me(void) {
std::cout << "I'm B" << std::endl;
}
};
class C : public A {
};
int main() {
A a;
B b;
C c;
A* p = &a;
p->print_me();
p = &b;
p->print_me();
p = &c;
p->print_me();
return 0;
}
Output:
I'm A
I'm B
I'm A