class A;
{
private:
int a;
public:
virtual int getV() { return a; }
} a;
class C : public A;
{
private:
int c;
public:
int getV() { return c; }
} c;
class D
{
public:
A* liste;
} d;
Memory for liste may be allocated and A::a and C::c are holding values. Now if I put c in D::liste[0] and give it out with
cout << d.liste[0].getV();
it prints A::a. Why doesn't it print out C::c although I declared A::getV() as virtual?
C++ polymorphism works only for pointers and references. liste[0] has type A, not A* or A&, so the liste[0].getV() call is not dispatched virtually. It just calls A::getV().
I wrote the program like this and getting the correct result as expected
#include <iostream>
using namespace std;
class A
{
private:
int a;
public:
virtual int getV() { cout<<"A";return a; }
};
class C : public A
{
private:
int c;
public:
virtual int getV() { cout<<"C";return c; }
};
class D
{
public:
A* liste[2];
};
int main()
{
D d;
d.liste[0]=new C();
d.liste[1]=new A();
cout<<d.liste[0]->getV();
return 0;
}
Just have a look at it..
Related
This question already has answers here:
C++ Call Pointer To Member Function
(4 answers)
Closed 5 years ago.
A have a lot of B classes, a class A has one object b. This object b has a function (calc) that needs a pointer to a method in an object of A. This method (fun) acess private variables in class (in my example just return 3).
class A;
class B {
public:
virtual int calc ( int (A::*fun)()) { return 2*fun(); };
};
class A {
B* b;
public:
A (B* b_) : b (b_) {};
int fun() { return 3; };
int run(){ return b->calc(&A::fun); };
};
int main() {
B* b = new B();
A a(b);
a.run();
return 0;
}
How can I use a pointer to a method correctly in definition of calc method in class B?
I am getting this error message:
teste.cpp:10:58: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘fun (...)’, e.g. ‘(... ->* fun) (...)’
virtual int calc ( int (A::*fun)()) { return 2*fun(); };
^
I recommend the std::function approach if it's feasible for you. However, for the sake of completeness, here's how you would correctly use pointer-to-member functions.
The pointer-to-member itself doesn't store the "current" instance of A, so you need to pass that explicitly. Then you use the special ->* (or .*) syntax to call it.
virtual int calc (A* value, int (A::*fun)()) {
return 2 * (value->*fun)();
};
Then you would call it as b->calc(this, &A::fun);.
You can do it your way, but the member function must be called on a particular instance:
class A;
class B {
public:
virtual int calc(A* a, int (A::*fun)()) { return 2 * (a->*fun)(); };
};
class A {
B* b;
public:
A(B* b_) : b(b_) {};
int fun() { return 3; };
int run() { return b->calc(this, &A::fun); }; // now also passing this pointer
};
int main() {
B* b = new B();
A a(b);
a.run();
return 0;
}
If you can live without calc() being virtual then a lambda is also an option:
class A;
class B {
public:
template<typename T>
int calc(T fun) { return 2 * fun(); };
};
class A {
B* b;
public:
A(B* b_) : b(b_) {};
int fun() { return 3; };
int run() {
return b->calc([this]() {return fun(); } );
};
};
int main() {
B* b = new B();
A a(b);
a.run();
return 0;
}
A pointer-to-class method is defined and initialized as (assuming SomeFn matches the signature):
RetType (ClassName::*pfn)(Args) = &ClassName::SomeFn;
And is called as:
ClassName * ptr = GetClassPtr();
(ptr->*pfn)(arg, arg);
If you are able to use C++11, then you should use std::function and std::bind: Otherwise you need to use a pointer to member function + a pointer to the instance.
With C++11
#include <functional>
class B {
public:
virtual int calc (std::function<int()>&& fun) { return 2 * fun(); }; };
};
class A {
B* b;
public:
A (B* b_) : b (b_) {};
int fun() { return 3; };
int run() { return b->calc(std::bind(&A::fun, this)); };
};
Without C++11
class B {
public:
virtual int calc (int(A::*fnptr)(), A* a) { return 2 * (a->*fnptr)(); };
};
class A {
B* b;
public:
A (B* b_) : b (b_) {};
int fun() { return 3; };
int run() { return b->calc(&A::fun, this); };
};
See example here.
I have the following code:
#include <iostream>
class A {
private:
int a;
public:
void setA(int a_);
friend int B::getA();
};
class B : public A {
public:
int getA();
};
void A::setA(int a_) {
a = a_;
}
int B::getA() {
return a;
}
int main() {
B myB;
myB.setA(9);
std::cout << myB.getA()<< std::endl;
return 0;
}
Compiling with g++ yields:
friend.cpp:10:16: error: use of undeclared identifier 'B'
friend int B::getA();
My thinking is that when the compiler is going through the class A definition, it does not yet know about class B. Therefore, I can forward declare B to take care of this problem:
#include <iostream>
class B;
class A {
...
That doesn't quite work:
friend.cpp:10:16: error: incomplete type 'B' named in nested name specifier
friend int B::getA();
It looks like the compiler isn't able to resolve the function as it is given.
How can I make a derived class function a friend in the base class?
Your code seems to violate the basic concept of data encapsulation. To resolve it, either make A::a protected, as #rici suggested, or define a getter in class A.
class A {
private:
int a;
public:
void setA(int a_);
virtual int getA();
};
class B : public A {
public:
int getA();
};
void A::setA(int a_) {
a = a_;
}
int A::getA() {
return a;
}
int B::getA() {
return A::getA();
}
I am trying to use functions that sets-gets a private variable of a derived class from base class objects. I think that is working for the void setC function but when i am trying to compile the getC function i get an error "Control reaches and non-void function". Is the whole concept possible?
class BASE{
int a, b;
public:
BASE(){}
BASE(int a, int b){
this->a = a;
this->b = b;
}
void setC(int){}
int getC(){}
};
class Derived : public BASE{
int c;
public:
void setC(int c) {
this->c = c;
}
int getC() {
return c;
}
};
int main(int argc, const char * argv[]) {
vector<BASE> d;
d.push_back(BASE(1,1));
d[0].setC(5);
cout << d[0].getC();
}
Implement getC and setC as (pure) virtual functions. And instantiate using derived class, like this:
class BASE {
public:
virtual void setC(int c) = 0;
virtual int getC() = 0;
};
class Derived : public BASE {
int c;
public:
virtual void setC(int c) { this->c = c; }
virtual int getC() { return c; }
};
void main() {
vector<BASE*> d;
d.push_back(new Derived());
d[0]->setC(5);
cout << d[0]->getC();
delete d[0];
}
PS. You got that error message because your BASE::getC doesn't return a value.
In order to get polymorphic behavior for getC(), you need the vector to be a vector of pointers, and declare getC and setC as virtual functions.
vector<BASE*> d;
Then
d.push_back(new DERIVED(1,1));
Will insert a new DERIVED object, and then
d[0]->getC()
will return the value from the derived object.
I'm fairly new to object-oriented program, so maybe this is a basic question, but I'd appreciate any help you can offer.
If I have a class B, which is derived from class A, is there some way for objects of class B to access class B's member functions from within member functions of class A? So in the example below I might have a call to function2 from within function1 if the object initially calling function1 is of type B. Is this possible, and if so, how do I accomplish it? Thanks!
class A
{
public:
int a;
int b;
A(){}
A(int a, int b) { this->a = a; this->b = b; }
int function1();// { call function2 if class B }
};
class B : public A
{
public:
int c;
int d;
B(){}
B(int c, int d) { this->c = c; this->d = d; }
int function2();
};
A function inside A doesn't have any idea of the fact that a class B which extends A exists and which methods it has.
To be able to invoke a specific method implemented in B from A you need to declare it in A as virtual, possibly pure virtual (= 0).
class A {
protected:
virtual void function2() = 0;
public:
void function1() { this->function2(); }
}
class B : public A {
protected:
void function2() override { ... }
}
A virtual method is resolved at runtime, this means that when invoked, the more specific implementation for the object on which it is called is executed. A pure virtual method doesn't have any base implementation, this makes A abstract and forbids its instantiation.
EDIT: a final note, don't call virtual methods from base constructors or destructors. It is dangerous and a bad practice, not that this is your case but you never know.
Yes. You need to define function2() as a virtual function in class A. Then calling it from function1 will result in B's function2() being called if the object is actually a B. For example:
class A
{
public:
int a;
int b;
A(){}
A(int a, int b) { this->a = a; this->b = b; }
int function1() { return this->function2(); }
virtual int function2() { return 0; }
};
class B : public A
{
public:
int c;
int d;
B(){}
B(int c, int d) { this->c = c; this->d = d; }
int function2() override { return 999; }
};
If there is no sensible implementation of function2 for A, then it would never make sense to have an A object. You can express this by declaring function2 to be pure virtual; e.g.
virtual int function2() = 0;
virtual allows you to override function in parent class.
class A
{
public:
A(){}
A(int a, int b):a(a), b(b) {}
int function1() { return this->function2(); }
virtual int function2() { //what function2 in parent class should do }
private:
int a;
int b;
};
class B : public A
{
public:
B(){}
B(int c, int d):c(c), d(d) {}
int function2() { //what function2 in child class should do }
private:
int c;
int d;
};
I was wondering if it's possible to override just one function in a class without creating an entirely new class.
I would like bObj1.foo(); to output "foo!" and bObj2.foo() to output "foo?", but currently they both output "foo!".
#include <iostream>
using namespace std;
class B {
public:
virtual void foo() { cout << "foo!" << endl; }
};
class A {
public:
B f();
};
B A::f() {
B bObj;
return bObj;
}
class C : public A {
};
int main()
{
A aObj;
B bObj1 = aObj.f();
bObj1.foo(); // "foo!"
C cObj;
B bObj2 = cObj.f();
bObj2.foo(); // "foo?"
}
You can get the behavior that you want with a simple change, which consists in moving the "virtual" behavior to the A and C classes.
Here I modified your application to return the expected result:
#include <iostream>
using namespace std;
class A;
class B {
public:
B(A& a) : aref(a) {}
void foo();
private:
A& aref;
};
class A {
public:
B f();
virtual void foo() { cout << "foo!" << endl; }
};
B A::f() {
B bObj(*this);
return bObj;
}
class C : public A {
public:
virtual void foo() { cout << "foo?" << endl; }
};
void B::foo() { aref.foo(); }
int main()
{
A aObj;
B bObj1 = aObj.f();
bObj1.foo(); // "foo!"
C cObj;
B bObj2 = cObj.f();
bObj2.foo(); // "foo?"
}
In order to change the virtual function, you have to create a new type - there's no way around that in C++. However, an alternate mechanism - function objects - may do what you want here.
#include <functional>
#include <iostream>
using namespace std;
class B {
public:
B(function<void ()> foo_impl) : foo_impl(foo_impl) {}
void foo() {foo_impl();}
private:
function<void()> foo_impl;
};
class A {
public:
virtual B f();
};
B A::f() {
B bObj([](){cout << "foo!" << endl;});
return bObj;
}
class C : public A {
public:
virtual B f() override;
};
B C::f() {
B bObj([](){cout << "foo?" << endl;});
return bObj;
}
int main()
{
A aObj;
B bObj1 = aObj.f();
bObj1.foo(); // "foo!"
C cObj;
B bObj2 = cObj.f();
bObj2.foo(); // "foo?"
}