I have an abstract base class called BaseStrategy. It contains one pure virtual function calculateEfficiency(). There are two classes ConvolutionStrategy and MaxPoolStrategy which derive from this base class and implement their own specific version of calculateEfficiency().
Here is some code:
class BaseStrategy {
public:
explicit BaseStrategy();
virtual ~BaseStrategy() = default;
private:
virtual double calculateEfficiency(mlir::Operation* op) = 0;
};
class ConvolutionStrategy : public BaseStrategy {
private:
double calculateEfficiency(mlir::Operation* op)
{
//some formula for convolution
return 1;
}
};
class MaxPoolStrategy : public BaseStrategy {
private:
double calculateEfficiency(mlir::Operation* op)
{
//some formula for MaxPool
return 1;
}
};
Now I have another class called StrategyAssigner. It has method calculateAllLayerEfficiencies() whose purpose is to iterate over all layers in a network. Depending on the type of layer there is a switch statement and should call the correct calculateEfficiency() depending on the layer type.
class StrategyAssigner final {
public:
explicit StrategyAssigner(){};
public:
void calculateAllLayerEfficiencies() {
// Logic to iterate over all layers in
// a network
switch (layerType) {
case Convolution:
// Call calculateEfficiency() for Convolution
break;
case MaxPool:
// Call calculateEfficiency() for MaxPool
break;
}
};
}
int main ()
{
StrategyAssigner assigner;
assigner.calculateAllLayerEfficiencies();
}
My question is, should I store references of objects Convolution and MaxPool in the class StrategyAssigner so that I can call the respective calculateEfficiency().
Or could you suggest a better way to call calculateEfficiency(). I don't really know how to create the objects (stupid as that sounds).
I can't make calculateEfficiency() static as I need them to be virtual so that each derived class can implemented its own formula.
If you included complete code I could give a more detailed answer, but you need to store BaseStrategy pointers that are initialized with derived class instances. Here's an example made from some of your code:
std::vector<std::unique_ptr<BaseStrategy>> strategies;
strategies.emplace_back(new ConvolutionStrategy);
strategies.emplace_back(new MaxPoolStrategy);
for (int i = 0; i < strategies.size(); ++i) {
std::unique_ptr<BaseStrategy>& pStrat = strategies[i];
pStrat->calculateEfficiency(...);
}
Note that this won't compile because I don't have enough details from the code you posted to make it so, but this shows how to exploit polymorphism in the way that you need.
Also, I used smart pointers for memory management; use these at your discretion.
You can indeed use runtime polymorphism here:
Declare ~BaseStrategy virtual (you are already doing it ;-)
If you are never going to instantiate a BaseStrategy, declare one of its methods as virtual pure, e.g. calculateEfficiency (you are already doing it as well!). I would make that method const, since it doesn't look it's going to modify the instance. And it will need to be public, because it will need to be accessed from StrategyAnalyser.
Declare calculateEfficiency as virtual and override in each of the subclasses. It could also be final if you don't want subclasses to override it.
I'd keep a std::vector of smart pointers to BaseStrategy at StrategyAssigner. You can use unique_ptrs if you think this class is not going to be sharing those pointers.
The key point now is that you create heap instances of the subclasses and assign them to a pointer of the base class.
class StrategyAssigner final {
public:
void addStrategy(std::unique_ptr<BaseStrategy> s) {
strategies_.push_back(std::move(s));
}
private:
std::vector<std::unique_ptr<BaseStrategy>> strategies_{};
};
int main()
{
StrategyAssigner assigner;
assigner.addStrategy(std::make_unique<ConvolutionStrategy>());
}
Then, when you call calculateEfficiency using any of those pointers to BaseStrategy, the runtime polymorphism will kick in and it will be the method for the subclass the one that will be actually called.
class ConvolutionStrategy : public BaseStrategy {
private:
virtual double calculateEfficiency() const override {
std::cout << "ConvolutionStrategy::calculateEfficiency()\n";
return 10;
}
};
class MaxPoolStrategy : public BaseStrategy {
private:
virtual double calculateEfficiency() const override {
std::cout << "MaxPoolStrategy::calculateEfficiency()\n";
return 20;
}
};
class StrategyAssigner final {
public:
void calculateAllLayerEfficiencies() {
auto sum = std::accumulate(std::cbegin(strategies_), std::cend(strategies_), 0,
[](auto total, const auto& strategy_up) {
return total + strategy_up->calculateEfficiency(); });
std::cout << "Sum of all efficiencies: " << sum << "\n";
};
};
int main()
{
StrategyAssigner assigner;
assigner.addStrategy(std::make_unique<ConvolutionStrategy>());
assigner.addStrategy(std::make_unique<MaxPoolStrategy>());
assigner.calculateAllLayerEfficiencies();
}
// Outputs:
//
// ConvolutionStrategy::calculateEfficiency()
// MaxPoolStrategy::calculateEfficiency()
// Sum of all efficiencies: 30
[Demo]
Hello everyone and thanks for reading,
I'm new to working with classes and I've ran into an issues with making array's of objects,
I have a base class, and an array of the same type, I'd like to know if it's a possibility to
make subclasses of the base class type and put them into an array and call methods that're not
in the base class, sorry if this is a bad question and my apologies if my wording is off,
#include <iostream>
int main()
{
BaseClass* ObjectList[10];
ObjectList[0] = new SubClass;
ObjectList[0]->Load(10);
ObjectList[0]->OtherFunction(); // How Can I Do This?
return 0;
}
class BaseClass
{
public:
virtual void Load(int Num) = 0;
};
class SubClass : public BaseClass
{
void Load(int Num) override
{
std::cout << Num << std::flush;
}
void OtherFunction()
{
// Do Something
}
};
Thanks
Edit -
My intent is to have a simple base class with dozens and dozens of subclasses with different methods, and have an array of the base class,
You can always have more than one pointer (or reference) to the same object.
int main()
{
BaseClass* ObjectList[10];
SubClass TheSubclass;
ObjectList[0] = &TheSubclass;
ObjectList[0]->Load(10); // presumably in a loop
TheSubclass.OtherFunction();
return 0;
}
You will have to downcast your pointer to the real class (or at least a class having the method). You can use either a static_cast if you do not need any control, or a dynamic_cast if you want a run-time validation of the cast:
...
SubClass *psc = dynamic_cast<SubClass *>(ObjectList[0]);
if (psc != nullptr) { // an invalid cast would set it to NULL
psc->OtherFunction();
}
else {
// process the error
}
I have 10 Coin types: BTC, ETH, Shift etc. For this I have a superclass "Coin" and subclasses for each of those coins. Then I have a pointer to a "Coin" type, so that I can call each of the subclasses no matter what subtype they are.
Problem is, I only know how to do this in Java and not in C++. I have a hard time searching for the correct terms, because I don't really know what to search for other than "generics". What I want is something like this:
// Superclass
class Coin {
public:
virtual void handleCoin();
};
// Subclass
class BTC: public Coin {
void handleCoin();
}
BTC::BTC() = default;
BTC::~BTC() = default;
BTC::handleCoin() {
std::cout << "handling BTC" << std::endl;
}
// Subclass
class ETH: public Coin {
void handleCoin();
}
ETH::ETH() = default;
ETH::~ETH() = default;
ETH::handleCoin() {
std::cout << "handling ETH" << std::endl;
}
// Execute
int main() {
Coin* coin;
coin = BTC();
coin.handleCoin();
coin = ETH();
coin.handleCoin();
return 0;
}
I want this to print:
handling BTC
handling ETH
I know I need to work with templates, but I cannot find a specific example of this specific case.
Also, my constructors don't take arguments, so I guess my template declaration would be something like
template<>
Yet all the examples I see work with
template<typename T>
and then use type T as function arguments like calling
max<float, float>
max<double, double>
But that's not what I'm looking for. Is there a way to translate this example above to working C++ code?
From the code posted I don't see a need for templates, virtual methods work without templates. To fix your code in main you need to use pointers/references and also have a virtual destructor.
class Coin {
public:
virtual void handleCoin();
virtual ~Coin()=default;
};
class BTC: public Coin {
public:
BTC::BTC() = default;
//Destructor of a derived class is automatically virtual if the base class's one is.
void handleCoin();
}
// Subclass
class ETH: public Coin {
void handleCoin();
ETH::ETH() = default;
//Still virtual even if you specify otherwise
ETH::~ETH() = default;
}
int main() {
Coin* coin;
coin = new BTC();//Returns BTC* <--pointer
coin->handleCoin();
delete coin;//Calls Coin::~Coin() -> thus the need for virtual so BTC::~BTC is called instead.
coin = new ETH();
coin->handleCoin();
delete coin;//Same, calls ETH::~ETH()
return 0;
}
Manual memory management is error-prone, from C++11 there's a better approach which should be strongly preferred:
int main() {
std::unique_ptr<Coin> coin;//Hides the pointer, but still has pointer-like semantics
coin = std::make_unique<BTC>();
coin->handleCoin();
//Automatically frees old memory
coin = std::make_unique<BTC>();
coin->handleCoin();
//Calls unique ptr's dtor because coin is local variable, which again frees the memory correctly.
return 0;
}
How do I allocate a polymorphic object on the stack? I'm trying to do something similar to (trying to avoid heap allocation with new)?:
A* a = NULL;
switch (some_var)
{
case 1:
a = A();
break;
case 2:
a = B(); // B is derived from A
break;
default:
a = C(); // C is derived from A
break;
}
You can't structure a single function to work like that, since automatic or temporary objects created inside a conditional block can't have their lifetimes extended into the containing block.
I'd suggest refactoring the polymorphic behaviour into a separate function:
void do_something(A&&);
switch (some_var)
{
case 1:
do_something(A());
break;
case 2:
do_something(B()); // B is derived from A
break;
default:
do_something(C()); // C is derived from A
break;
}
Disclaimer: I definitely don't think this is a good solution. The good solutions are to either rethink the design (maybe OO polymorphism is not warranted here given that there is a bounded number of possibilities?), or to use a second function to pass along said polymorphic object by reference.
But since other folks mentioned this idea, but got details wrong, I'm posting this answer to show how to get it right. Hopefully I get it right.
It is clear the the number of possible types is bounded. This means that a discriminated union, like boost::variant could solve the problem, even if it's not pretty:
boost::variant<A, B, C> thingy =
some_var == 1? static_cast<A&&>(A())
: some_var == 2? static_cast<A&&>(B())
: static_cast<A&&>(C());
The fact that now you can use things like static visitors is one if the things that keeps making me think this isn't a good use of OO polymorphism.
If instead of a ready-made solution, you want to use placement new by hand as suggested in other answers, there are a number of things that need care because we lose some of the properties of regular automatic objects in the process:
the compiler no longer gives us the right size and alignment;
we no longer get an automatic call to the destructors;
In C++11, these are both easy to fix with aligned_union and unique_ptr, respectively.
std::aligned_union<A, B, C>::type thingy;
A* ptr;
switch (some_var)
{
case 1:
ptr = ::new(&thingy.a) A();
break;
case 2:
ptr = ::new(&thingy.b) B();
break;
default:
ptr = ::new(&thingy.c) C();
break;
}
std::unique_ptr<A, void(*)(A*)> guard { ptr, [](A* a) { a->~A(); } };
// all this mechanism is a great candidate for encapsulation in a class of its own
// but boost::variant already exists, so...
For compilers that don't support these features, you can get alternatives: Boost includes aligned_storage and alignment_of traits which can be used to build aligned_union; and unique_ptr can be replaced with some kind of scope guard class.
Now that that is out of the way, just so it's clear, don't do this and simply pass a temporary along to another function, or revisit the design altogether.
If B is your base types D1, D2, and D3 are your derived types:
void foo()
{
D1 derived_object1;
D2 derived_object2;
D3 derived_object3;
B *base_pointer;
switch (some_var)
{
case 1: base_pointer = &derived_object1; break;
....
}
}
If you want to avoid wasting the space of the three derived objects, you could break up your method into two parts; the part that chooses which type you need, and the part of the method that works on it. Having decided which type you need, you call a method that allocates that object, creates a pointer to it, and calls the second half of the method to complete the work on the stack-allocated object.
I wrote a generic template to do it. Full code available here (it became too elaborate for the scope of this question).
StackVariant object contains a buffer of the size of the biggest type out of the provided types, and biggest alignment as well. The Object is constructed on the stack using a 'placement new' and operator->() is used for polymorphic access to suggest the indirection. Also, it is important to make sure that if a virtual detor is defined, it should be called upon destruction of the object on the stack, so the template detor is doing just that using a SFINAE definition.
(see usage example and output below):
// compile: g++ file.cpp -std=c++11
#include <type_traits>
#include <cstddef>
// union_size()/union_align() implementation in gist link above
template<class Tbaseclass, typename...classes>
class StackVariant {
alignas(union_align<classes...>()) char storage[union_size<classes...>()];
public:
inline Tbaseclass* operator->() { return ((Tbaseclass*)storage); }
template<class C, typename...TCtor_params>
StackVariant& init(TCtor_params&&...fargs)
{
new (storage) C(std::forward<TCtor_params>(fargs)...); // "placement new"
return *this;
};
template<class X=Tbaseclass>
typename std::enable_if<std::has_virtual_destructor<X>::value, void>::type
call_dtor(){
((X*)storage)->~X();
}
template<class X=Tbaseclass>
typename std::enable_if<!std::has_virtual_destructor<X>::value, void>::type
call_dtor() {};
~StackVariant() {
call_dtor();
}
};
Usage example:
#include <cstring>
#include <iostream>
#include "StackVariant.h"
class Animal{
public:
virtual void makeSound() = 0;
virtual std::string name() = 0;
virtual ~Animal() = default;
};
class Dog : public Animal{
public:
void makeSound() final { std::cout << "woff" << std::endl; };
std::string name() final { return "dog"; };
Dog(){};
~Dog() {std::cout << "woff bye!" << std::endl;}
};
class Cat : public Animal{
std::string catname;
public:
Cat() : catname("gonzo") {};
Cat(const std::string& _name) : catname(_name) {};
void makeSound() final { std::cout << "meow" << std::endl; };
std::string name() final { return catname; };
};
using StackAnimal = StackVariant<Animal, Dog, Cat>;
int main() {
StackAnimal a1;
StackAnimal a2;
a1.init<Cat>("gonzo2");
a2.init<Dog>();
a1->makeSound();
a2->makeSound();
return 0;
}
// Output:
// meow
// woff
// woff bye!
Few things to note:
I wrote it while trying to avoid heap allocations in performance critical functions and it did the job - 50% speed gains.
I wrote it to utilize C++'s own polymorphic mechanisms. Before that my code was full of switch-cases like the previous suggestions here.
You can't create a polymorphic local variable
You can't create a polymorphic local variable, since a subclass B of A might have more attributes than A, thus take more place, so the compiler would have to reserve enough space for the largest subclass of A.
In case you have dozens of subclasses, and one of them has a large number of attributes, this would waste a lot of space.
In case you put in the local variable an instance of a subclass of A you received as a parameter, and you put your code in a dynamic library, then the code linking with it could declare a subclass larger than those in your library, so the compiler wouldn't have allocated enough space on the stack anyway.
So allocate space for it yourself
Using placement new, you can initialize the object in a space you allocated through some other means:
alloca, but seeing this SO question it seems it's not the best option.
A Variable Length Array, with which comes some (non-)portability fun, since it works under GCC but isn't in the C++ standard (not even in C++11)
aligned_union<A, B, C>::type, as suggested by R. Martinho Fernandes in a comment to this answer
However, these techniques may use a lot of extra space, and don't work if you are given a reference (pointer) to an unknown-at-compile-time subclass of A that is larger than the types you accounted for.
The solution I propose is to have a kind of factory method on each subclass, that calls a supplied function with a pointer to a stack-allocated instance of the given subclass. I added an extra void* parameter to the supplied function's signature, so one can pass it arbitrary data.
#MooingDuck suggested this implementation using templates and C++11 in a comment below. In case you need this for code that can't benefit from C++11 features, or for some plain C code with structs instead of classes (if struct B has a first field of type struct A, then it can be manipulated somewhat like a "substruct" of A), then my version below will do the trick (but without being type-safe).
This version works with newly defined subclasses, as long as they implement the ugly factory-like method, and it will use a constant amount of stack for the return address and other informations required by this intermediate function, plus the size of an instance of the requested class, but not the size of the largest subclass (unless you choose to use that one).
#include <iostream>
class A {
public:
int fieldA;
static void* ugly(void* (*f)(A*, void*), void* param) {
A instance;
return f(&instance, param);
}
// ...
};
class B : public A {
public:
int fieldB;
static void* ugly(void* (*f)(A*, void*), void* param) {
B instance;
return f(&instance, param);
}
// ...
};
class C : public B {
public:
int fieldC;
static void* ugly(void* (*f)(A*, void*), void* param) {
C instance;
return f(&instance, param);
}
// ...
};
void* doWork(A* abc, void* param) {
abc->fieldA = (int)param;
if ((int)param == 4) {
((C*)abc)->fieldC++;
}
return (void*)abc->fieldA;
}
void* otherWork(A* abc, void* param) {
// Do something with abc
return (void*)(((int)param)/2);
}
int main() {
std::cout << (int)A::ugly(doWork, (void*)3);
std::cout << (int)B::ugly(doWork, (void*)1);
std::cout << (int)C::ugly(doWork, (void*)4);
std::cout << (int)A::ugly(otherWork, (void*)2);
std::cout << (int)C::ugly(otherWork, (void*)11);
std::cout << (int)B::ugly(otherWork, (void*)19);
std::cout << std::endl;
return 0;
}
By then, I think we might have outweighed the costs of a simple malloc, so you might wand to use that after all.
You can do it with placement new. This will place the items on the stack, in the memory contained in the buffer. However, these variables are not automatic. The downside is that your destructors won't run automatically, you would need to properly destruct them just as you've created them when they go out of scope.
A reasonable alternative to manually calling the destructor is to wrap your type in a smart pointer, as shown below:
class A
{
public:
virtual ~A() {}
};
class B : public A {};
class C : public B {};
template<class T>
class JustDestruct
{
public:
void operator()(const T* a)
{
a->T::~T();
}
};
void create(int x)
{
char buff[1024] // ensure that this is large enough to hold your "biggest" object
std::unique_ptr<A, JustDestruct<T>> t(buff);
switch(x)
{
case 0:
ptr = new (buff) A();
break;
case 1:
ptr = new (buff) B();
break;
case 2:
ptr = new (buff) C();
break;
}
// do polymorphic stuff
}
Polymorphism doesn't work with values, you need a reference or a pointer. You can use a const reference to a temporary object polymorphically and it will have the lifetime of a stack object.
const A& = (use_b ? B() : A());
If you need to modify the object, you have no choice but to dynamically allocate it (unless you're using Microsoft's non-standard extension that lets you bind a temporary object to a non-const reference).
A combination of a char array and placement new would work.
char buf[<size big enough to hold largest derived type>];
A *a = NULL;
switch (some_var)
{
case 1:
a = new(buf) A;
break;
case 2:
a = new(buf) B;
break;
default:
a = new(buf) C;
break;
}
// do stuff with a
a->~A(); // must call destructor explicitly
To strictly answer your question - what you have now does just that - i.e. a = A(); and a = B() and a = C(), but these objects are sliced.
To achieve polymorphic behavior with the code you have, I', afraid that's not possible. The compiler needs to know the size beforehand of the object. Unless you have references or pointers.
If you use a pointer, you need to make sure it doesn't end up dangling:
A* a = NULL;
switch (some_var)
{
case 1:
A obj;
a = &obj;
break;
}
won't work because obj goes out of scope. So you're left with:
A* a = NULL;
A obj1;
B obj2;
C obj3;
switch (some_var)
{
case 1:
a = &obj1;
break;
case 2:
a = &obj2;
break;
case 3:
a = &obj3;
break;
}
This of course is wasteful.
For references it's a bit trickier because they have to be assigned on creation, and you can't use temporaries (unless it's a const reference). So you'll probably need a factory that returns a persistent reference.
trying to avoid heap allocation with new)?
Well in that case you create object on stack as usual and assign address to the base pointer. But remember, if this is done inside a function, don't pass the address as return value, because stack will unwind after the function call returns.
So this is bad.
A* SomeMethod()
{
B b;
A* a = &b; // B inherits from A
return a;
}
It is possible, but it's a lot of effort to do cleanly (without manual placement new and exposed raw buffers, that is).
You're looking at something like Boost.Variant, modified to restrict the types to a base class and some derived classes, and to expose a polymorphic reference to the base type.
This thing (PolymorphicVariant ?) would wrap all the placement new stuff for you (and also take care of safe destruction).
If it's really what you want, let me know and I'll give you a start. Unless you really need exactly this behaviour though, Mike Seymour's suggestion is more practical.
Run this short program and you'll see why polymorphic objects do not work on the stack very well. When you create a stack object of a derived type that is unknown and expect it to be returned from a function call, what happens is the object is destroyed when that calling function goes out of scope. Thus the object only lives as long as that function is within scope. In order to return a valid object that will outlive the calling function you need to use the heap. This is demonstrated with this simple hierarchy and two versions of the same function with a switch statement except one does the stack and the other does it on the heap. Look at the output from both implementations and look to see what methods are called, what class they are being called from and when they are being called.
#include <string>
#include <iostream>
class Base {
public:
enum Type {
DERIVED_A = 0,
DERIVED_B,
DERIVED_C
};
protected:
Type type_;
public:
explicit Base(Type type) : type_(type) {
std::cout << "Base Constructor Called." << std::endl;
}
virtual ~Base() {
std::cout << "Base Destructor Called." << std::endl;
}
virtual void doSomething() {
std::cout << "This should be overridden by derived class without making this a purely virtual method." << std::endl;
}
Type getType() const { return type_; }
};
class DerivedA : public Base {
public:
DerivedA() : Base(DERIVED_A) {
std::cout << "DerivedA Constructor Called." << std::endl;
}
virtual ~DerivedA() {
std::cout << "DerivedA Destructor Called." << std::endl;
}
void doSomething() override {
std::cout << "DerivedA overridden this function." << std::endl;
}
};
class DerivedB : public Base {
public:
DerivedB() : Base(DERIVED_B) {
std::cout << "DerivedB Constructor Called." << std::endl;
}
virtual ~DerivedB() {
std::cout << "DerivedB Destructor Called." << std::endl;
}
void doSomething() override {
std::cout << "DerivedB overridden this function." << std::endl;
}
};
class DerivedC : public Base {
public:
DerivedC() : Base(DERIVED_C) {
std::cout << "DerivedC Constructor Called." << std::endl;
}
virtual ~DerivedC() {
std::cout << "DerivedC Destructor Called." << std::endl;
}
void doSomething() override {
std::cout << "DerivedC overridden this function." << std::endl;
}
};
Base* someFuncOnStack(Base::Type type) {
Base* pBase = nullptr;
switch (type) {
case Base::DERIVED_A: {
DerivedA a;
pBase = dynamic_cast<Base*>(&a);
break;
}
case Base::DERIVED_B: {
DerivedB b;
pBase = dynamic_cast<Base*>(&b);
break;
}
case Base::DERIVED_C: {
DerivedC c;
pBase = dynamic_cast<Base*>(&c);
break;
}
default: {
pBase = nullptr;
break;
}
}
return pBase;
}
Base* someFuncOnHeap(Base::Type type) {
Base* pBase = nullptr;
switch (type) {
case Base::DERIVED_A: {
DerivedA* pA = new DerivedA();
pBase = dynamic_cast<Base*>(pA);
break;
}
case Base::DERIVED_B: {
DerivedB* pB = new DerivedB();
pBase = dynamic_cast<Base*>(pB);
break;
}
case Base::DERIVED_C: {
DerivedC* pC = new DerivedC();
pBase = dynamic_cast<Base*>(pC);
break;
}
default: {
pBase = nullptr;
break;
}
}
return pBase;
}
int main() {
// Function With Stack Behavior
std::cout << "Stack Version:\n";
Base* pBase = nullptr;
pBase = someFuncOnStack(Base::DERIVED_B);
// Since the above function went out of scope the classes are on the stack
pBase->doSomething(); // Still Calls Base Class's doSomething
// If you need these classes to outlive the function from which they are in
// you will need to use heap allocation.
// Reset Base*
pBase = nullptr;
// Function With Heap Behavior
std::cout << "\nHeap Version:\n";
pBase = someFuncOnHeap(Base::DERIVED_C);
pBase->doSomething();
// Don't Forget to Delete this pointer
delete pBase;
pBase = nullptr;
char c;
std::cout << "\nPress any key to quit.\n";
std::cin >> c;
return 0;
}
Output:
Stack Version:
Base Constructor Called.
DerivedB Constructor Called.
DerivedB Destructor Called.
Base Destructor Called.
This should be overridden by derived class without making this a purely virtual method.
Heap Version:
Base Constructor Called.
DerivedC Constructor Called.
DerivedC overridden this function.
DerivedC Destructor called.
Base Destructor Called.
I'm not saying that it can not be done; I'm just stating the caveats in trying to do so. It may be ill-advised to try to do something of the sort. I do not know of any way to do this unless if you have a wrapper class that will contain the stack allocated objects to manage their life time. I'll have to try and work on that to see if I can come up with something of the sort.
Let's say I have a class box, and a user can create boxes. How to do it? I understand I create objects by className objectName(args); but how to do it dynamically, depending on the user input?
The correct answer depends on the number of different classes of which you want to create the instances.
If the number is huge (the application should be able to create an instance of any class in your application), you should use the reflection functionality of .Net. But, to be honest, I'm not a big fan of using reflection in business logic, so I would advise not to do this.
I think that in reality you have a limited number on classes for which you want to create instances. And all the other answers make this assumption. What you actually need is a factory pattern. In the next code I also assume that the classes of which you want to create instances, all derive from the same base class, let's say Animal, like this:
class Animal {...};
class Dog : public Animal {...}
class Cat : public Animal {...}
Then create an abstract factory which is an interface that creates an animal:
class IFactory
{
public:
Animal *create() = 0;
};
Then create subclasses for each of the different kinds of animals. E.g. for the Dog class this will become this:
class DogFactory : public IFactory
{
public:
Dog *create() {return new Dog();}
};
And the same for the cat.
The DogFactory::create method overrules the IFactory::create method, even if their return type is different. This is what is called co-variant return types. This is allowed as long as the return type of the subclass's method is a subclass of the return type of the base class.
What you can now do is put instances of all these factories in a map, like this:
typedef std::map<char *,IFactory *> AnimalFactories
AnimalFactories animalFactories;
animalFactories["Dog"] = new DogFactory();
animalFactories["Cat"] = new CatFactory();
After the user input, you have to find the correct factory, and ask it to create the instance of the animal:
AnimalFactories::const_iterator it=animalFactories.find(userinput);
if (it!=animalFactories.end())
{
IFactory *factory = *it;
Animal *animal = factory->create();
...
}
This is the typical abstract factory approach.
There are other approaches as well. When teaching myself C++ I wrote a small CodeProject article about it. You can find it here: http://www.codeproject.com/KB/architecture/all_kinds_of_factories.aspx.
Good luck.
The following factory method creates Box instances dynamically based on user input:
class BoxFactory
{
public:
static Box *newBox(const std::string &description)
{
if (description == "pretty big box")
return new PrettyBigBox;
if (description == "small box")
return new SmallBox;
return 0;
}
};
Of course, PrettyBigBox and SmallBox both derive from Box. Have a look at the creational patterns in the C++ design patterns wikibook, as one of them probably applies to your problem.
In C++, it is possible to allocate objects using automatic (stack) and dynamic (heap) storage.
Type variable_name; // variable_name has "automatic" storage.
// it is a local variable and is created on the stack.
Type* pointer_name = NULL; // pointer_name is a "pointer". The pointer, itself,
// is a local variable just like variable_name
// and is also created on the stack. Currently it
// points to NULL.
pointer_name = new DerivedType; // (where DerivedType inherits from Type). Now
// pointer_name points to an object with
// "dynamic" storage that exists on the heap.
delete pointer_name; // The object pointed-to is deallocated.
pointer_name = NULL; // Resetting to NULL prevents dangling-pointer errors.
You can use pointers and heap-allocation to dynamically construct objects as in:
#include <cstdlib>
#include <iostream>
#include <memory>
class Base {
public:
virtual ~Base(){}
virtual void printMe() const = 0;
protected:
Base(){}
};
class Alpha : public Base {
public:
Alpha() {}
virtual ~Alpha() {}
virtual void printMe() const { std::cout << "Alpha" << std::endl; }
};
class Bravo : public Base {
public:
Bravo() {}
virtual ~Bravo() {}
virtual void printMe() const { std::cout << "Bravo" << std::endl; }
};
int main(int argc, char* argv[]) {
std::auto_ptr<Base> pointer; // it is generally better to use boost::unique_ptr,
// but I'll use this in case you aren't familiar
// with Boost so you can get up and running.
std::string which;
std::cout << "Alpha or bravo?" << std::endl;
std::cin >> which;
if (which == "alpha") {
pointer.reset(new Alpha);
} else if (which == "bravo") {
pointer.reset(new Bravo);
} else {
std::cerr << "Must specify \"alpha\" or \"bravo\"" << std::endl;
std::exit(1);
}
pointer->printMe();
return 0;
}
Related: the "Factory" object-oriented design pattern