c++ additional features in subclass not in superclass - c++

Suppose I have the following code:
class A
{
public:
void Funct1();
};
class B : public A
{
public:
void Func1();
void Func2();
}
In main()
Declaring Object of type A
A b = new B;
b.Func1() // can access it;
b.Func2() // cannot access
How can I make or access Func2 using object b especially in main

There are a few problems in your code.
You are using Void instead of void. Notice the uppercase vs lowercase difference.
You are using Funct1 in A but Func1 in B. You can change Funct1 to Func1
There is a missing ; at the end of B.
Using B instead of new B. You have:
A b = new B;
That is a syntactically incorrect line. You can make it either
A b = B();
or
A* b = new B();
Even after that change, you still have the problems you described.
There are two ways you can solve this:
Use B b instead A b.
B b;
b.Func1();
b.Func2();
Use a virtual member function.
class A
{
Public:
void Func1();
virtual void Func2();
};
class B : public A
{
Public:
void Func1();
virtual void Func2();
};
Then, you can use:
B b;
A* aPtr = &b;
aPtr->Func1();
aPtr->Func2();

You may use static_cast
A *b = new B;
B *bb = static_cast<B*> (b);
through bb you can access Func2().

Write a function which gets argument of Type A. Then you can send an argument of type A or B to this function,polymorphism works and the function inside class A or B works wrt what you want.

In a statically typed language like C++, you can only call methods corresponding to the static type of an object in the current scope. In main, you declared b with static type A, restricting it to the interface defined in class A. If you want polymorphism, you need to declare the polymorphic functions in A and also add the virtual keyword.

If object-oriented programming doesn't make sense for the problem you are trying to solve, don't use it. In C++, you don't need to put everything in classes, let alone in class hierarchies. Start with simple free-standing functions and use classes if you need them.
That being said, if you really insist, use dynamic_cast. In some situations, this may even be a legitimate choice. But if you feel that you need it all the time, then you must review your understanding of object-oriented programming.

Related

How can an pointer of superclass access variables of subclass?

I have a class A and class B which inherits from class A. Class B has a variable and a function that are not available in class A. I made a pointer
A* ptr=new B();
So how can ptr access the variable and function that belongs to class B?
Class A simply cannot "see" the functions of class B. Instead, you'd have to use something like a dynamic_cast from A to B, check for null, and then proceed as you like. Here is a nice tutorial to explain this a lot better than I can. Each of the casts have their advantages and disadvantages; learn them well. Also, try to avoid C style casting.
EDIT : Seems I misread the question. The answer is still correct, though. Class A would not be able to "see" the variables of Class B. The casting would still allow you access to them.
You can force the derived class to implement a pure virtual method defined in the base class:
class A
{
public:
virtual void do_things() = 0;
};
class B : public A
{
public:
virtual void do_things()
{
//Implementation
}
};
This way you can call the method implemented by class B through a pointer A*:
A* a_ptr = new B();
//The method implemented in class B will be called
a_ptr->do_things();
You could also make the assumption that a_ptr points to an object of class B. If a_ptr doesn't point to a B the pointer returned by dynamic_cast<B*> will be a nullptr. You can use static_cast<B*> if there are no virtual methods in A.
b_ptr = dynamic_cast<B*>(a_ptr);
b_ptr->do_things;
This way you don't need the pure virtual function in class A.

C++ function overload for classes

I have 3 classes
class A {
//...
}
class B : public A {
//...
}
And a class C:
#include "A.h"
#include "B.h"
class C
{
void method(A anObjOfA);
void method(B anObjOfB);
}
Now if I do
B* ptr = new B();
A* ptrToB = ptr;
c.method(*ptrToB);
It calls the method for Objects of type A, not the inherited actual type B.. How can I make sure the right function for the object deepest in the inheritence-tree is called, without actually knowing it's type at compile-time?
PS: I'm sure this is a noob question, for the life of me I can't find any results on this here, as everyone is busy understanding the "virtual" keyword, which is perfectly clear to me but is not the issue here.
Because resolving a function overload is done at compile-time. When you call the function it only sees the A part of the pointer, even though it could point to a B.
Perhaps what you want is the following:
class A
{
public:
virtual void DoWorkInC()
{
cout << "A's work";
}
virtual ~A() {}
};
class B : public A
{
public:
virtual void DoWorkInC()
{
cout << "B's work";
}
};
class C
{
void method(A& a)
{
a.DoWorkInC();
}
}
Let your class A, B have virtual function implemented in their respectivbe classes:
class A {
//...
public:
virtual void doTask();
};
class B : public A {
//...
public:
void doTask();
};
Ket A::doTask() and B::doTask() do respective tasks in object specific way, i.e. A::doTask() to do tasks with visibility of the object set as an A object, and B::doTask() to do tasks with visibility of the object set as an B object.
Now, let the call be like this:
B* ptr = new B();
A* ptrToB = ptr;
c.method(ptrToB); // pointer is passed
Within C::method(A *ptr), it may be something like:
void C::method(A * ptr) {
ptr->doTask(); this would actuall call A::doTask() or B::doTask() as dynamically binded
}
thanks to #texasbruce I found the answer, RTTI
The code will look like this:
A* someAOrBPtr = ...
...
B* testBPtr = dynamic_cast<B*>(someAOrBPtr);
if( testBPtr ){
// our suspicions are confirmed -- it really was a B
C->method(testBPtr);
}else{
// our suspicions were incorrect -- it is definitely not a B.
// The someAOrBPtr points to an instance of some other child class of the base A.
C->method(someAOrBPtr);
};
EDIT: In fact, I'll probably do the dynamic cast inside the C->method so there is only one
C::method(A* ptrOfBase)
and then do the appropriate thing (taking in or out the respective container-member-variable of C) inside the one 'method' of C.
Compiler is not smart enough to guess which method you wanna call. In the same situation of yours, you might actually want to call the the first version since you are using a A*. This leaves the programmer to work on: be specific. If you don't want to use ptr (which call the second version as you wished), you need to specifically cast it:
c.method(*((B*)ptrToB));
or better using dynamic cast:
c.method(*dynamic_cast<B*>(ptrToB));
This could be unsafe because you are "downcasting" in which case dynamic cast may throw exception and C style cast won't but will cause memory leak. You have to be very careful.

Pointer to virtual function

So I'm in a bit of a dilemma right now. I want to make a function pointer, but I want to make it to a virtual function. Not necessarily the virtual function itself, but the derived one. I tried just making the pointer, but the function needs to be static. When I try to make a static virtual function, the compiler yells at me. I also don't want to make the function pointer class specific so conceivably other classes could use the pointer. Here is what I mean in pseudocode:
class C
{
public:
virtual void something();
};
class B : public C
{
public:
void something();
};
class D
{
public:
void something();
};
int main()
{
void(*pointer)();
B b;
D d;
pointer = b.something.
pointer();
pointer = d.something;
pointer()
}
Something is not a static method but I want the pointer to be able to point to it. Also the pointer can point to other class methods that are also not static. Is there anything I can do with this?
EDIT
I finally was able to figure out how to do this. I had to use std::function. This should also work for just regular member functions, not necessarily virtual one. Here is what it would look like:
class A
{
public:
virtual void something(int i);
};
class B
{
virtual void somethingElse(int i);
}
//This isn't needed, it just saves typing if you have multiple pointers
typedef std::function<void(int)> functionType
functionType* pointer;
int main()
{
B b;
A a;
pointer = std::bind(&A::something,&a,std::placeholders::_1);
pointer(1)
pointer = std::bind(&B::somethingElse,&b,std::placeholders::_1);
pointer(4)
}
Theres quite a bit on the internet on std::bind, so if you're curious you can read about it.
I found this particularly helpful, as it has a very similar solution to what I have.
std::function to member function
Thanks to all who have helped.
You won't be able to assign a pointer-to-member function to a normal function pointer: function pointers don't take any additional arguments while member function take an implicit this pointer as argument. You might want to use a std::function<...>, though:
std::function<void()> pointer;
B b;
pointer = std::bind(&C::something, &b);
pointer();
D d;
pointer = std::bind(&c::something, &d);
pointer();
You could avoid using std::function<...> if you pass a pointer to the object and a suitable member function pointer around and there is common base class (while the code above works with the missing inheritance, the code below requires that C is a base of D):
void (C::*member)() = &C::something;
C* c = &b;
(c->*member)(); // calls b.something() using B::something()
c = &d;
(c->*member)(); // calls d.something() using D::something()
C++ doesn't have a notation using &object.member to get the address of a readily bound member function. ... and, even if it did, its type wouldn't be void(*)() either.
void(B::*bPointer)();
void(D::*dPointer)();
B b;
D d;
bPointer = &B::something;
(b.*bpointer)();
dPointer = &D::something;
(d.*dPointer)();
You can also use std::mem_fn and std::bind.
There are so many things wrong here it's hard to know where to begin.
This:
void(*pointer)();
does not declare a pointer-to-member-function. It declares a pointer-to-free-function (eg, non-member function). These two types of pointers are completely unrelated, and you cannot convert between the two. You can not assign the address of a member function to a pointer-to-free-function, or vice versa.
You need to declare a pointer-to-member with special syntax. The old (C++03) syntax would be:
void (C::*memFn)()
However, since the type of the pointer includes information about the class that the function is a member of, now you can't assign the address D::something() to memFn -- C and D are completely unrelated as well.
You mentioned that you wanted to create a "static virtual method." There's no such thing. In fact the two concepts "static" and "virtual" are almost completely orthogonal to each other. The idea simply makes no sense. It's like saying you want to plant an apple hammer.
Why are you trying to use the D object as if it were a B object? D and B are completely unrelated. It seems to me like what you really should be trying to do is have an abstract base class, A, and 2 concrete implementations of that ABC, B and C. Then a pointer to an A could point to either a B or a C, and you could call virtual methods of the same name and get different behavior.
Finally, for the last couple of days you have posted questions that indicate that you are struggling to learn the language by banging out some code and trying to fix whatever compiler errors result. (I might be thinking of someone else, if so I'm sorry) That's not going to work. Have you taken my advice and gotten a good C++ text yet?
S.th. like
pointer = &D::dosomething;
May be??
Note:
You'll need to have an actual instance of D to call non-static class members.
#include <iostream>
class A
{
private:
int i;
protected:
void (A::*ptr)();
public:
A() : i(0), ptr(&A::methodOne) {}
virtual ~A(){}
void move_ptr()
{
switch(++i)
{
case 0: {ptr = &A::methodOne;} break;
case 1: {ptr = &A::methodTwo;} break;
case 2: {ptr = &A::methodThree;} break;
case 3: {ptr = &A::nonVirtual;} break;
default: {ptr = &A::methodOne; i = 0;} break;
}
}
void call() {(this->*A::ptr)();}
virtual void methodOne() {std::cout<<"A::methodOne\n";}
virtual void methodTwo() {std::cout<<"A::methodTwo\n";}
virtual void methodThree() {std::cout<<"A::methodThree\n";}
void nonVirtual() {std::cout<<"A::nonVirtual\n";}
};
class B : public A
{
public:
B() : A() {}
virtual ~B(){}
virtual void methodOne() {std::cout<<"B::methodOne\n";}
virtual void methodTwo() {std::cout<<"B::methodTwo\n";}
virtual void methodThree() {std::cout<<"B::methodThree\n";}
void nonVirtual() {std::cout<<"B::nonVirtual\n";}
};
int main()
{
A a;
a.call();
a.move_ptr();
a.call();
a.move_ptr();
a.call();
a.move_ptr();
a.call();
B b;
b.call();
b.move_ptr();
b.call();
b.move_ptr();
b.call();
b.move_ptr();
b.call();
}
Prints:
A::methodOne
A::methodTwo
A::methodThree
A::nonVirtual
B::methodOne
B::methodTwo
B::methodThree
A::nonVirtual
I'll leave it to you to figure out why the last line is A::nonVirtual instead of B::nonVirtual. Once you figure that out, you'll already know how to fix it.

How do you implement polymorphic behaviour with multiple inheritance?

I have never used multiple inheritance but while reading about it recently I started to think about how I could use it practically within my code. When I use polymorphism normally I usually use it by creating new derived instances declared as base class pointers such as
BaseClass* pObject = new DerivedClass();
so that I get the correct polymorphic behaviour when calling virtual functions on the derived class. In this way I can have collections of different polymorphic types that manage themselves with regards to behaviour through their virtual functions.
When considering using multiple inheritance, I was thinking about the same approach but how would I do this if I had the following hierarchy
class A {
virtual void foo() = 0;
};
class B : public A {
virtual void foo() {
// implementation
}
};
class C {
virtual void foo2() = 0;
};
class D : public C {
virtual void foo2() {
// implementation
}
};
class E : public C, public B {
virtual void foo() {
// implementation
}
virtual void foo2() {
// implementation
}
};
with this hierarchy, I could create a new instance of class E as
A* myObject = new E();
or
C* myObject = new E();
or
E* myObject = new E();
but if I declare it as a A* then I will lose the polymorphism of the class C and D inheritance hierarchy. Similarly if I declare it as C* then I lose the class A and B polymorphism. If I declare it as E* then I cannot get the polymorphic behaviour in the way I usually do as the objects are not accessed through base class pointers.
So my question is what is the solution to this? Does C++ provide a mechanism that can get around these problems, or must the pointer types be cast back and forth between the base classes? Surely this is quite cumbersome as I could not directly do the following
A* myA = new E();
C* myC = dynamic_cast<C*>(myA);
because the cast would return a NULL pointer.
With multiple inheritance, you have a single object that you can view any of multiple different ways. Consider, for example:
class door {
virtual void open();
virtual void close();
};
class wood {
virtual void burn();
virtual void warp();
};
class wooden_door : public wood, public door {
void open() { /* ... */ }
void close() { /* ... */ }
void burn() { /* ... */ }
void warp() { /* ... */ }
};
Now, if we create a wooden_door object, we can pass it to a function that expects to work with (a reference or pointer to) a door object, or a function that expects to work with (again, a pointer or reference to) a wood object.
It's certainly true that multiple inheritance will not suddenly give functions that work with doors any new capability to work with wood (or vice versa) -- but we don't really expect that. What we expect is to be able to treat our wooden door as either a door than can open and close, or as a piece of wood that can burn or warp -- and that's exactly what we get.
In this case, classes A and C are interfaces, and E implements two
interfaces. (Typically, you wouldn't have intermediate classes C and
D in such a case.) There are several ways of dealing with this.
The most frequent is probably to define a new interface, which is a sum
of A and C:
class AandC : public A, public C {};
and have E derive from this. You'd then normally manage E through a
AandC*, passing it indifferently to functions taking an A* or a
C*. Functions that need both interfaces in the same object will deal
with AandC*.
If the interfaces A and C are somehow related, say C offers
additional facilities which some A (but not all) might want to
support, then it might make sense for A to have a getB() function,
which returns the C* (or a null pointer, if the object doesn't support
the C interface).
Finally, if you have mixins and multiple interfaces, the cleanest
solution is to maintain two independent hierarchies, one for the
interfaces, and another with the implementation parts:
// Interface...
class AandC : public virtual A, public virtual C {};
class B : public virtual A
{
// implement A...
};
class D : public virtual C
{
// implement C...
};
class E : public AandC, private B, private D
{
// may not need any additional implementation!
};
(I'm tempted to say that from a design point of view, inheritance of
interface should always be virtual, to allow this sort of thing in the
future, even if it isn't needed now. In practice, however, it seems
fairly rare to not be able to predict this sort of use in advance.)
If you want more information about this sort of thing, you might want to
read Barton and Nackman. There book is fairly dated now (it describes
pre C++98), but most of the information is still valid.
This should work
A* myA = new E();
E* myC = dynamic_cast<E*>(myA);
myC->Foo2();
C can't cast to A because it isn't an A; it can only cast down to D or E.
Using A* you can make an E* and through that you can always explicitly say things like C::foo() but yes, there is no way for A to implicitly call functions in C that might have overrides or might not.
In weird cases like this, templates are often a good solution because they can allow classes to act as if they have common inheritance even if they don't. For instance, you might write a template that works with anything that can have foo2() invoked on it.

How to Call Function of one class on the object of another class?

How can I call one method in one class over using another class ?
I have ;
class A {
public :
foo ( ) ;
};
class B {
public :
bar ( ) ;
};
in main :
A data ; // I am creating instance of class A
data . bar ( ) ; // but, I am calling a method of another class
// how can I do that ?
Note : I could not find a appropriate title. If you have one, feel free to share or edit
Unless the two classes are related(through inheritance) You cannot do that.
A member functions performs some action on the instance of the class to which it belongs.
You created an object of class A so you can only call member functions of A through it.
Grinding an Apple and hoping to get a mango shake, won't really happen right.
Use public inheritance:
class B {
public:
void bar();
};
class A : public B
{ };
int main() {
A a;
a.bar();
}
I think if you want use .bar() on A object A must inherit by B.
It is not clear what you want data.bar() to do.
bar() as no access to A's data, so bar() cannot have anything to do with the variable data. So, I would argue, that data.bar() is unnecessary, you are aiming for just bar().
Presumably, if bar() is just a function, you can declare it static and call B.data()
The other option is that you wanted inheritance which some other people have already written about. Be careful with inheritance, and make sure you inherit A from B only if you there is a is-a relationship, and it satisfies the Liskov Principle. Don't inherit from B just because you have to call bar().
If you want to use B, you can have a instance of B inside A. Read about prefering composition over inheritance
As everyone said in their answers.
Its a bad idea and not possible.
You can only use tricks that no one really knows how its gonna behave.
You can get the pointer of an object A and cast it to be poiter of B.
Again the only use of that is to show other what not to do.
A a;
B* b = (B*)&a;
b->bar();
I think you should read 1 or 2 c plus plus book(s) and get a fair idea what classes are about and what purpose they are meant to serve.
Some suggestions: The c++ programing by Bjarne Stroustrup or Thinking in c++ by Bruce Eckel or search over net for tutorials.
You can use a function pointer. The only way to make it not static is to use templates.
class A
{
public:
void setBar(void (*B::func)(void)) { bar = func; };
void callBar() { bar(); };
private:
void(*B::bar)(void);
};
class B
{
public:
static void bar() { printf("you called bar!"); };
};
int main() {
A a;
a.setBar(B::bar);
a.callBar();
}
You can also declare class B as a friend of class A.
I believe the syntax for it is:
class A {
public:
foo();
friend class B;
};
class B {
public:
bar();
};
But with this, I believe you can only use functions/variables from A inside B functions.
Inheritance will probably be your better approach to it.
Although this question is strange !, but here are some solutions
Using inheritance
class A: public B
Type cast
A data;
((B*)&data)->bar();
Or reinterpret cast
B* b = reinterpret_cast <B*> (&data);
b->bar();
If bar() use any member variables of B, then the result is not predictable.