Dynamically instance objects (like a template)

I'm trying to create a template blueprint type class and trying to figure out the best way to handle instancing a new class (From a templated) class. Essentially use a class to dynamically instance objects from. This may seem stupid but I need the class (Shapes) to hold their own object of type 'types' Something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Shape{
    vector<Types> shapes; 
    MyShape Create(){
        foreach(auto shape in shapes){  
           //Create a new instance each shape here
           //Along the lines of?
           //shape s();       
       }
    }
}

class Circle : Shape{
    Circle(){
        this->shapes.push_back("A CLASS OF SHAPE");
    }
}

Circle cir();
//I'd change the return type, to either a vector or just push each instance back to a vector but just using the below as an example. 
MyShape myShape = cir->Create();


I'm coming from C# so please tell me if this is bad practice.
Last edited on
What are you trying to accomplish? You know that in C# any complex object is accessed via a pointer. In C++ you can use [smart] pointer to gain the same effect.

In C++ you can store the entire object in a container. Whether that makes sense depends on the use of this object.
This won't make much sense till I show an example, I want the base class to handle the instancing / logic of the inherited class because I don't want to manually write hundreds of shapes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class SuperBar{
    //...
}

class Bar : public SuperBar{
    //...
} 

class Foo : ManufactureSuperBar{
    vector<map<int, Bar>> requiredNumberToInstanceBar;

    Foo(){
        Bar bar();
        requiredNumberToInstanceBar.push_back(std::make_pair(12, bar); 

        //OR pass in something like this
        ManufactureSuperBar::Create(12, bar);
    }
}

class ManufactureSuperBar{
    Create(int amount, SuperBar superBar){
          if(amount > 10)
               ...
    }
}



C# would look like this:

 
    SuperBar sb = new Bar();

Last edited on
I want the base class to handle the instancing / logic of the inherited class because I don't want to manually write hundreds of shapes.

IOW, you want a factory function or method:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Bar { virtual ~Bar() = default; }; // base class 
struct D0: Bar {}; // derived type 0
struct D1: Bar {}; // derived type 1
// ...

using A = some_type;
// place this depending on your needs
// e.g., if the base-class constructor is protected
std::unique_ptr<Bar> make_bar(A selector) {
  if   (selector == D0_selected) return std::make_unique<D0>();
  else (selector == D1_selected) return std::make_unique<D1>();
  else return nullptr;
}
Last edited on
C# would look like this:
In C++:
SuperBar *sb = new Bar();



I don't want to manually write hundreds of shapes:
Of course not. It seems to me that you want a container of all derived shapes in the shape class itself. I don't think it makes too much sense.

Again: C# and C++ are so closely related that you can achieve absolutely the same in both languages just with some minor syntax differences. I do actually work with both languages. In C++ you might find more elegant solution because it is less restricted.
Thanks for your replies

@mbozzi- I'm trying to call the constructor of the smart pointer, how is that done?

1
2
3
4
5
6
7
8
9
    class Bar : Foo{
        Bar(string name) : Foo(name){
            //...
        }
    }
    
    std::unique_ptr<Foo> make_bar() {
	return std::make_unique<Bar>();
    }


Thanks guys!
Pass the constructor arguments to std::make_unique<> (It is a variadic template).

For example:
1
2
3
4
std::unique_ptr<Foo> make_bar( const std::string& name ) {

	return std::make_unique<Bar>(name);
}


Note: To avoid undefined behaviour, the base class Foo must have a virtual destructor.
LAST question guys, is it possible to create the virtual function with a template?:

1
2
3
4
5
6
	template<class T>
	virtual std::unique_ptr<FOO> Create(string name) {
		return std::make_unique<T>(name);
	}

        MyBase::Create<Bar>(name);


Or another way that would be best to call the base class? I for some reason still think. MyBase:: can be done better.
Last edited on
No.
17.6.2/3 A member function template shall not be virtual. http://eel.is/c++draft/temp.mem


Perhaps you could be clearer about what is it that you are trying to achieve.
Topic archived. No new replies allowed.