1

I have 3 classes, A, B and C:

class A {  
public:  
 virtual bool sm(B b) = 0; 
 virtual bool sm(C c) = 0; 
};  

class B : public A {  
 bool sm(B b) {
  //code
 }
 bool sm(C c) {
  //code
 }
};  

class C : public A {  
 bool sm(B b) {
  //code
 }
 bool sm(C c) {
  //code
 }
};  

And vector<A*> objects, that stores B or C objects. (for example they generates randomly)
Can I call somehow

for(int i = 0; i < objects.size(); i++) {
 for(int j = i; j < objects.size(); j++) {
  objects[i].sm(objects[j]);
 }
}

Without dynamic cast or something? Because there can be a bit more of B-C classes
And is it a bag thing, and may be there is a better way to do it?

SOLUTION
As odelande said and I understood, this is the solution for my problem

#include <iostream>
#include <vector>

class B;
class C;

class A {
public:
    virtual bool sm(A* a) = 0;
    virtual bool sm(B* b) = 0;
    virtual bool sm(C* c) = 0;
};

class B : public A {
public:
    bool sm(A* a) {
        return a->sm(this);
    }
    bool sm(B* b) {
        std::cout << "In B doing B" << std::endl;
        return true;
    }
    bool sm(C* c) {
        std::cout << "In B doing C" << std::endl;
        return false;
    }
};

class C : public A {
public:
    bool sm(A* a) {
        return a->sm(this);
    }
    bool sm(B* b) {
        std::cout << "In C doing B" << std::endl;
        return true;
    }
    bool sm(C* c) {
        std::cout << "In C doing C" << std::endl;
        return false;
    }
};

int main() {
    std::vector<A*> objects;
    objects.push_back(new B());
    objects.push_back(new C());
    objects[0]->sm(objects[0]);
    objects[0]->sm(objects[1]);
    objects[1]->sm(objects[0]);
    objects[1]->sm(objects[1]);
    std::cin.get();
    return 0;
}

This code outputs

In B doing B
In C doing B
In B doing C
In C doing C

Masafi
  • 151
  • 2
  • 15
  • 1
    Search for "double dispatch" – Brian Bi Jun 10 '16 at 21:01
  • @Brian, thanks, that seems that i looking for – Masafi Jun 10 '16 at 21:04
  • Per Brian's comment, here is a link or two about double dispatch - [Difference betwen Visitor pattern & Double Dispatch](http://stackoverflow.com/questions/9818132/difference-betwen-visitor-pattern-double-dispatch) as well as [The Visitor pattern and multiple dispatch](https://blogs.msdn.microsoft.com/devdev/2005/08/29/the-visitor-pattern-and-multiple-dispatch/) – Richard Chambers Jun 10 '16 at 21:08

2 Answers2

0

You cannot do it like this. The overloads of the sm() method are statically resolved, i.e. at compile time (besides, sm() should take pointers to B and C). But the compiler only knows that objects[j] is an A*; it cannot resolve the call because there is no overload that takes a A* as input.

What you want is to dispatch the call based on the runtime type of objects[j]. This is what a call to a virtual function does. So, you should only have one sm() method, which should in turn call another virtual method of its argument.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
odelande
  • 311
  • 2
  • 6
0

You're searching for the Visitor Pattern, multiple dispatch. The key is that you take a reference in sm(A& a) and call smT(...) on it. (Code is for example purposes only, will need clean-up and consts.)

class A {
protected:
 virtual bool smB(B& b) = 0; 
 virtual bool smC(C& c) = 0; 
public:  
 virtual bool sm(A& a) = 0; 
};  

class B : public A {  
protected:
 bool smB(B& b) {
  // code, 
 }
 bool smC(C& b) {
  // code
 }
public:
 bool sm(A& a) {
  a.smB( *this ); // this is smC(...) in class C
 }
};
lorro
  • 10,687
  • 23
  • 36