C ++ how to implement transition between class members

I am very new to C ++, so I'm trying to figure out how to do things right in C ++. I have a class that uses one of two members. which is determined at instantiation. It looks like

main() {
    shared_pointer<A> a = make_shared<A>(); 
    if ( checkSomething ) { 
        a->setB(make_shared<B>()); 
    } else {
        a->setC(make_shared<C>()); 
    }
    a->doStuff();

class A {
    public:
        doStuff() {

        /*here I want to do something like call 
        m_b->doStuff() if this pointer is set and m_c->doStuff() if 
        that pointer is set.*/

       }

        setB( B* p ) { m_b = p; }
        setC( C* p ) { m_c = p; }
        B* m_b;
        C* m_c;
    }
}
B and C are some classes with doStuff() member function

There are many members like doStuff. Ideally, I would not check the nullptr value in each of them. What is the best / most efficient / fastest way to create a switch between the two members?

Is there a way to use a static pointer so that I have a member

static **int m_switch;

and do something like

m_switch = condition ? &m_b : &m_c;

and call

*m_switch->doStuff();

Here, the compiler also replaces the extra pointer because it is static?

Is there any other smart way to make these keys?

+4
source share
4

A , B, C . , .

, :

class A_interface
{
public:
    virtual void doStuff() = 0;
    virtual void doThings() = 0;
    virtual void doBeDoBeDo() = 0;
};

:

template< class T >
class A : public A_interface
{
public:
   void doStuff() override { target.doStuff(); }
   void doThings() override { target.doThings(); }
   void doBeDoBeDo() override { target.doBeDoBeDo(); }

private:
    T target;
};

, A, . , , , :

std::shared_ptr<A_interface> a;

if( checkSomething ) {
    a = std::make_shared<A<B>>();
} else {
    a = std::make_shared<A<C>>();
}

a->doStuff();
+4

. . :

  • ( , doStuff)

. , , . ,

class IDoesStuff
{
public:
    virtual ~IDoesStuff() {};
    virtual void DoStuff() = 0;
};

:

class Foo : public IDoesStuff
{
public:
    virtual void DoStuff()
    {
        // ....
    }
};

class Bar : public IDoesStuff
{
public:
    virtual void DoStuff()
    {
        // ....
    }
};

, , :

Foo foo;
IDoesStuff *stuffDoer= &foo;

stuffDoer->doStuff();

:

class A
{
    IDoesStuff *stuffDoer; // Initialize this at some point.

public:
    void doStuff() { stuffDoer->doStuff(); }
};
+1

, , . B C.

// existing classes
class B
{
public:
  void doStuff() { std::cout << "B"; }
};

class C
{
public:
  void doStuff() { std::cout << "C"; }
};

// define your interface
class I
{
public:
  virtual void doStuff() = 0;
};

// new classes
class D : public B, public I
{
public:
  void doStuff() override { B::doStuff(); }
};

class E : public C, public I
{
public:
  void doStuff() override { C::doStuff(); }
};

// your A class
class A
{
public:
  D* b = nullptr; // now type D
  E* c = nullptr; // now type E

  // your toggle
  I* getActive()
  {
    if (b)
      return b;
    else
      return c;
  }

  // simple doStuff() function
  void doStuff()
  {
    getActive()->doStuff();
  }
};

int main()
{
  A a;
  if (true)
    a.b = new D; // need to initialize as D
  else
    a.c = new E; // need to initialize as E

  a.doStuff(); // prints B
}

, , D E , . , @paddy.

+1

First you have to change the variables memebr m_band m_con std::shared_ptr.

Add a member variable of the type std::function(void())to hold the target function that you want to call. In your example, this do_stuf.

In your setter functions, you can bind the target function to yours std::functionand do_stufsimply call it std::function.

(you need a C ++ 11 compiler)

class B
{
public:
    void doStuff() 
    {
    }
};

class C
{
public:
    void doStuff()
    {
    }
};

class A 
{
public:
    void doStuff() 
    {
        m_target_function();
    }

    void setB(std::shared_ptr<B> p)
    {
        m_b = p;

        m_target_function = std::bind(&B::doStuff, m_b.get());
    }
    void setC(std::shared_ptr<C> p)
    {
        m_c = p;

        m_target_function = std::bind(&C::doStuff, m_c.get());
    }

    std::shared_ptr<B> m_b;
    std::shared_ptr<C> m_c;

    std::function<void()> m_target_function;
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::shared_ptr<A> a = std::make_shared<A>();

    bool use_B = false;

    if (use_B) 
    {
        a->setB(std::make_shared<B>());
    }
    else 
    {
        a->setC(std::make_shared<C>());
    }

    a->doStuff();
}
+1
source

Source: https://habr.com/ru/post/1660886/


All Articles