One pointer, two different classes in C ++

Suppose I have two structures aand b, each of which contains several variables (most of the variable are C ++ kernel types, but not all).

Is there a way to create a pointer with a name cthat can point to any of them? Also, is there a way to create a kit that can contain any of them?

thank

+5
source share
8 answers

The usual way to create a pointer that can point to either of the two is to make them inherit from a common base class. Any pointer to a base class can point to any subclass. Note that in this way you can access elements that are part of the base class through this pointer:

class Base {
public:
    int a;
};

class Sub1 : public Base {
public:
    int b;
};

class Sub2 : public Base {
public:
    int c;
};


int main() {
    Base* p = new Sub1;
    p.a = 1; // legal
    p.b = 1; // illegal, cannot access members of sub-class
    p = new Sub2; // can point to any subclass
}

What you are trying to achieve is called polymorphism , and this is one of the fundamental concepts of object-oriented programming. One way to access a member of a subclass is to lower the pointer. When you do this, you must make sure that you apply it to the correct type:

static_cast<Sub1*>(p).b = 1; // legal, p actually points to a Sub1
static_cast<Sub2*>(p).c = 1; // illegal, p actually points to a Sub1

, , , ( ):

std::set<Base*> base_set;
base_set.insert(new Sub1);
base_set.insert(new Sub2);
+3

, , ?

Boost.Any Boost.Variant. 2 , variant . "", any.

any variant.

#include <boost/any.hpp>
#include <boost/variant.hpp>

#include <vector>

class A { };
class B { };
class C { };

int main()
{
    // any

    std::vector<boost::any> anies;
    anies.push_back(A());
    anies.push_back(B());

    A a0 = boost::any_cast<A>(anies[0]);
    A b0 = boost::any_cast<A>(anies[1]); // throws boost::bad_any_cast

    // variant
    std::vector<boost::variant<A,B> > vars;
    vars.push_back(A());
    vars.push_back(B());

    A a1 = boost::get<A>(vars[0]);
    A b1 = boost::get<A>(vars[1]); // throws boost::bad_get

    // and here is the main difference:
    anies.push_back(C()); // OK
    vars.push_back(C());  // compile error
}

: variant, , 2 . variant, .

+4

a b , void* , , boost any.

a b, a*.

+3

, . OOP, Object.

+1

C A, B of C. A B ( ), C .

:

A *a = new A();
B *b = new B();
C *c;

c = a;

c = b;
0

, ? - " a b", , .

,

if( p->type == 'a' ) {
   ... a-specific stuff
} else if( p->type == 'b' ) {
   ... b-specific stuff
} ...

.

" " , - , ++ .

class Interface {
 public:
    virtual void doClientStuff() = 0; // 
    virtual ~theInterface(){};
};

class A : public Interface {
    virtual void doClientStuff(){ ... a-specific stuff }
};

class B : public Interface {
    virtual void doClientStuff(){ ... b-specific stuff }
};

- , ++.

void clientCode( Interface* anObject ) {
   anObject->doClientStuff();
}

Interface* i = new A();
Interface* j = new B();

clientCode( i );
clientCOde( j );
0

:

  • , .
  • void * .
  • - , # 1.
  • .

, . , union . , . :

// Declarations ...
class FirstType;
class SecondType;

union PointerToFirstOrSecond {
   FirstType* firstptr;
   SecondType* secondptr;
};

enum FIRST_OR_SECOND_TYPE {
   FIRST_TYPE,
   SECOND_TYPE
};

struct PointerToFirstOrSecondContainer {
   PointerToFirstOrSecond pointer;
   FIRST_OR_SECOND_TYPE which;
};

// Example usage...

void OperateOnPointer(PointerToFirstOrSecondContainer container) {
    if (container.which == FIRST_TYPE) {
       DoSomethingWith(container.pointer.firstptr);
    } else {
       DoSomethingElseWith(container.pointer.secondptr);
    }
}

, "firstptr" "secondptr" ( ), .

, , , . . , .

0

!!!! -

, . ( )

, . ... simple:

// abstract base class
#include <iostream>
using namespace std;

class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area (void) =0;
};

class Rectangle: public Polygon {
  public:
    int area (void)
      { return (width * height); }
};

class Triangle: public Polygon {
  public:
    int area (void)
      { return (width * height / 2); }
};

int main () {
  Polygon * ppoly1 = new Rectangle (4,5);
  Polygon * ppoly2 = new Triangle (4,5);
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  cout << ppoly1->area() << '\n';
  cout << ppoly2->area() << '\n';
  return 0;
}
0
source

All Articles