Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
215 views
in Technique[技术] by (71.8m points)

c++ - Creating a new object from dynamic type info

In C++, is there any way to query the type of an object and then use that information to dynamically create a new object of the same type?

For example, say I have a simple 3 class hierarchy:

class Base
class Foo : public Base
class Bar : public Base

Now suppose I give you an object cast as type Base -- which is in reality of type Foo. Is there a way to query the type and use that info to later create new objects of type Foo?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Clone method

There is nothing provided by the language that queries type and lets you construct from that information, but you can provide the capability for your class heirarchy in various ways, the easiest of which is to use a virtual method:

struct Base {
  virtual ~Base();
  virtual std::auto_ptr<Base> clone(/*desired parameters, if any*/) const = 0;
};

This does something slightly different: clone the current object. This is often what you want, and allows you to keep objects around as templates, which you then clone and modify as desired.

Expanding on Tronic, you can even generate the clone function.

Why auto_ptr? So you can use new to allocate the object, make the transfer of ownership explicit, and the caller has no doubt that delete must deallocate it. For example:

Base& obj = *ptr_to_some_derived;
{ // since you can get a raw pointer, you have not committed to anything
  // except that you might have to type ".release()"
  Base* must_free_me = obj.clone().release();
  delete must_free_me;
}
{ // smart pointer types can automatically work with auto_ptr
  // (of course not all do, you can still use release() for them)
  boost::shared_ptr<Base> p1 (obj.clone());
  auto_ptr<Base>          p2 (obj.clone());
  other_smart_ptr<Base>   p3 (obj.clone().release());
}
{ // automatically clean up temporary clones
  // not needed often, but impossible without returning a smart pointer
  obj.clone()->do_something();
}

Object factory

If you'd prefer to do exactly as you asked and get a factory that can be used independently of instances:

struct Factory {}; // give this type an ability to make your objects

struct Base {
  virtual ~Base();
  virtual Factory get_factory() const = 0; // implement in each derived class
    // to return a factory that can make the derived class
    // you may want to use a return type of std::auto_ptr<Factory> too, and
    // then use Factory as a base class
};

Much of the same logic and functionality can be used as for a clone method, as get_factory fulfills half of the same role, and the return type (and its meaning) is the only difference.

I've also covered factories a couple times already. You could adapt my SimpleFactory class so your factory object (returned by get_factory) held a reference to a global factory plus the parameters to pass to create (e.g. the class's registered name—consider how to apply boost::function and boost::bind to make this easy to use).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...