C++ Multiple inheritance problem on accessing second derived class variables - c++

I have a base class A and in this class, there is a vector of the derived class B, and I add class C objects to this list (C is a derived class of B).
But now I am not able to access any variable either from B or C.
My class structure goes like this:
Skill.h
class Skill
{
public:
Skill()
{
}
vector <AttackSkill*> attacks;
vector <UtilitySkill*> utilities;
vector <MoveSkill*> movement;
};
AttackSkill.h
#pragma once
#include "Skill.h"
class AttackSkill :
public Skill
{
public:
AttackSkill()
{
}
string skillName;
int dmgMod;
int baseAcc;
};
One of the skills
#pragma once
#include "AttackSkill.h"
class Axeblade :
public AttackSkill
{
public:
Axeblade()
{
skillName = "Axeblade";
dmgMod = 0;
baseAcc = 72;
}
};
This is how to add new skill
attacks.push_back(new Axeblade);
I just want to be able to access variables.
Example:
"skillPtr" is a pointer to Skill object
for (int i = 0; i < skillPtr->attacks.size(); i++) //No problem here
{
cout << "Skill " << i << ") " << skillPtr->attacks[i]->skillName << endl;
}
Error C2039 'skillName': is not a member of 'Skill'

I am doing some guesswork here since the question is not fully specific but it might help…
Your class Skill contains three vectors (aggregation) and it’s inherited by subclasses defining skill types (inheritance). You should break these two principles apart. There should be one class containing the vectors for a character, let me call it SkillSet. (By the way, you should never issue using namespace in a header file.)
class SkillSet
{
public:
std::vector <AttackSkill *> attacks;
std::vector <UtilitySkill *> utilities;
std::vector <MoveSkill *> movement;
};
Then there will be another base class for all skills which would contain the properties which all skills have:
class Skill
{
public:
std::string skillName;
};
Then you can inherit this new Skill class:
class AttackSkill :
public Skill
{
public:
int dmgMod;
int baseAcc;
};
class Axeblade :
public AttackSkill
{
public:
Axeblade()
{
skillName = "Axeblade";
dmgMod = 0;
baseAcc = 72;
}
};
After creating and filling a SkillSet object:
SkillSet hero0;
hero0.attacks.push_back(new Axeblade);
You can simply access its public members:
std::cout << hero0.attacks[0]->skillName;
See the example of my code.
A few more notes to consider:
You don’t need vectors of pointers, you can put the objects directly to the vector. A vector is not a plain array.
Instead of making the properties public, consider using setters and getters.
Your code contains empty constructors. There is no need to write a constructor that is empty.
On the other hand, if your code contains objects created using new, you should delete them, e.g. in a destructor.

Related

C++ polymorphism: how to create derived class objects

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]

Acessing subclass variable from base class object

Let's say i'm having the following classes in c++
class Animal{}
class Dog : public Animal {
int barkingVolume;
}
However, i don't have the header file for Dog class. But i have the object of Dog of type Animal at runtime.
The question is how I can access the variable barkingVolume?
Animal animalButDogObject;//someone has set the value at runtime
I need to access barkingVolume from animalButDogObject.
Actual scenario from COM/Directshow: I'm having IBaseFilter object which is of type IVendorFilter(custom filter from 3rd party vendor which extended IBaseFilter). While debugging using Visual studio i can see the type is IVendorFilter and it has variables which i need to change. However i cannot figure out how to do it. I cannot find anything like a reflection/evalutation in CPP
I'd rather comment than post an answer, but can't due to lack of reputation, so here we go.
This is pretty bad, but if you know the exact layout of the class you must access, you could just forward declare the whole thing and reinterpret_cast the object you need.
// FooBar.cpp or something
namespace FooBar
{
class Foo {};
class Bar : public Foo
{
public:
Bar(int ival, float fval) : ival(ival), fval(fval) {}
int ival = 0;
float fval = 0.0f;
};
}
// OtherFile.cpp
class ForwardDeclaredBar
{
public:
int ival;
float fval;
};
#include <iostream>
int main()
{
FooBar::Foo* foo = new FooBar::Bar(3, 2.7f);
auto bar = reinterpret_cast<ForwardDeclaredBar*>(foo);
std::cout << "ival = " << bar->ival << ", fval = " << bar->fval << std::endl; // shows expected values
return 0;
}
Again, this is pretty bad since any changes to the "real" class will mess up your result (reinterpret_cast will just shove whatever data it finds into the format you specified).
There are probably many other reasons which I've no idea about. I'm also unsure how well (if at all) this plays with more complex objects.
declare method on Animal (base) class and overwrite it on Dog (derived) class.
// Base class
class Animal
{
public:
virtual int getBarkingVolume() = 0;
};
// Derived class
class Dog : public Animal
{
private:
int barkingVolume = 8;
public:
int getBarkingVolume()
{
return barkingVolume;
}
};
In main method has Animal (base) type and each derived class that implements the appropriate method (getBarkingVolume) will be compatible with that type.
int main()
{
Animal* animal = new Dog();
std::cout<<"barking: "<< animal->getBarkingVolume();
}

Do I need to initiate parent class or just child class

I am new in programing and I am analyzing code with parent class fruit and child classes apple and pear. In this example there is pointer to parent class. After I extended this code I find out that using object I can access parent public members and all child members. Question is why do I need those pointers?
// are this pointer needed since I can use j.setWeight(11)
#include <iostream>
using namespace std;
class fruit {
private:
int weight;
public:
void setWeight(int x)
{
weight = x;
}
int getWeight()
{
return weight;
}
};
class apple : public fruit {
public:
void eat()
{
cout << "Now I am eating apple"
<< "=" << getWeight() << endl;
}
};
class pear : public fruit {
public:
void eat()
{
cout << "Now I am eating pear"
<< " = " << getWeight() << endl;
}
};
int main()
{
apple j;
pear k;
fruit* fruit1 = &j;
fruit* fruit2 = &k;
k.setWeight(5);
k.eat();
fruit1->setWeight(11);
apple apple;
apple.postaviTezinu(16);
apple.jelo();
return 0;
}
are this pointers needed since I can use j.setWeight(11) and results is same as
fruit1 -> setWeight(11) ... what s difference, thx
I suspect that the code you are looking at was written to demonstrate how pointers to base classes can be used with objects of derived classes. No, pointers are not necessary for the functionality of this learning exercise. In fact, that is probably the reason this functionality was chosen. Since you see how to accomplish the same thing without pointers, it should be easier for you to relate pointers to what you already know.
The key learning points I see in this exercise are
The same pointer type (fruit *) can point to objects of different types (apple or pear).
When using the pointer to the base class, you can access base class members.
When using the pointer to the base class, you cannot access derived class members. (Implied by omission; compare what is done with k to what is done with fruit1.)
You will need to move on to the more advanced lessons to learn when pointers are more useful than accessing objects directly (probably after eat() is turned into a virtual function). For now, just learn how the same task can be accomplished by different means.
(Sure, you could get that information here, but that code looks like it's part of a series. Continuing with that series might be the better way to learn.)
Since you're new to programming, learning polymorphism may be a bit advanced for you at this stage. To answer your question directly: No, you don't need pointers in your example code, and they are in no way helpful.
However, pointers to objects are often useful for:
Reducing unnecessary copying of objects
In the case of polymorphism (as in your example) pointers help in sections of your programme where you don't know which object type you're dealing with, or don't want to have to deal with them in different ways
Example:
#include <iostream>
#include <vector>
class A
{
public:
virtual void foo ()
{
std::cout << " I am A\n";
}
};
class B : public A
{
public:
virtual void foo ()
{
std::cout << " I am B\n";
}
};
void bar ( const std::vector <A*> & obj )
{
// Here it outputs the foo () function that is
// appropriate for the class
for ( unsigned int i = 0; i < obj . size (); ++i )
obj [i] -> foo ();
}
int main ()
{
A a1, a2, a3;
B b1, b2, b3;
// the below input style requires C++11,
// otherwise input them one-by-one
std::vector <A*> array {&a1, &b1, &a2, &a3, &b2, &b3};
bar ( array );
return 0;
}
The above array can store any A objects, including the inherited objects (it can't do this without pointers); and the bar function can still perform operations on the elements in the array without needing to know which object type they belong to within the inheritance tree (due to the virtual function). This is crucial for taking advantage of polymorphism, and saving on repetition of functions and code in general.

Dynamically creating an instance of a class from a string containing the class name in C++

Lets say I have a base class with 100 children:
class Base {
virtual void feed();
...
};
class Child1 : public Base {
void feed(); //specific procedure for feeding Child1
...
};
...
class Child100 : public Base {
void feed(); //specific procedure for feeding Child100
...
};
At runtime I want to read a file that contains which children to create and feed. Lets say I've read the file and the vector of strings "names" contains the names of the child classes (ie. Child1, Child4, Child99). Now I'm going to iterate through these strings, create an instance of the specific child, and feed it with its specific feeding procedure:
vector<Base *> children;
for (vector<string>::iterator it = names.begin(); it != names.end(); ++it) {
Base * child = convert_string_to_instance(*it)
child->feed()
children.push_back(child);
}
How would I create the function convert_string_to_instance() such that if it takes in the string "Child1" it returns a "new Child1", if the string argument is "Child4" it returns a "new Child4", etc
<class C *> convert_string_to_instance(string inName) {
// magic happens
return new C; // C = inName
// <brute force?>
// if (inName == "Child1")
// return new Child1;
// if (inName == "Child2")
// return new Child2;
// if (inName == "Child3")
// return new Child3;
// </brute force>
}
C++ does not provide a method for dynamic construction of class instances like this. However, you may be able to use code generation to generate the "brute force" code (like you showed above) from a list of classes. Then, #include the generated code in your convert_string_to_instance method.
You can also set up your project build system to rebuild the generated code anytime the list of classes changes.
I asked a question entitled automatic registration of object creator function with a macro that has the following example program that runs:
#include <map>
#include <string>
#include <iostream>
struct Object{ virtual ~Object() {} }; // base type for all objects
struct ObjectFactory {
static Object* create(const std::string& id) { // creates an object from a string
const Creators_t::const_iterator iter = static_creators().find(id);
return iter == static_creators().end() ? 0 : (*iter->second)(); // if found, execute the creator function pointer
}
private:
typedef Object* Creator_t(); // function pointer to create Object
typedef std::map<std::string, Creator_t*> Creators_t; // map from id to creator
static Creators_t& static_creators() { static Creators_t s_creators; return s_creators; } // static instance of map
template<class T = int> struct Register {
static Object* create() { return new T(); };
static Creator_t* init_creator(const std::string& id) { return static_creators()[id] = create; }
static Creator_t* creator;
};
};
#define REGISTER_TYPE(T, STR) template<> ObjectFactory::Creator_t* ObjectFactory::Register<T>::creator = ObjectFactory::Register<T>::init_creator(STR)
namespace A { struct DerivedA : public Object { DerivedA() { std::cout << "A::DerivedA constructor\n"; } }; }
REGISTER_TYPE(A::DerivedA, "A");
namespace B { struct DerivedB : public Object { DerivedB() { std::cout << "B::DerivedB constructor\n"; } }; }
REGISTER_TYPE(B::DerivedB, "Bee");
namespace C { struct DerivedC : public Object { DerivedC() { std::cout << "C::DerivedC constructor\n"; } }; }
REGISTER_TYPE(C::DerivedC, "sea");
namespace D { struct DerivedD : public Object { DerivedD() { std::cout << "D::DerivedD constructor\n"; } }; }
REGISTER_TYPE(D::DerivedD, "DEE");
int main(void)
{
delete ObjectFactory::create("A");
delete ObjectFactory::create("Bee");
delete ObjectFactory::create("sea");
delete ObjectFactory::create("DEE");
return 0;
}
compile and run output is:
> g++ example2.cpp && ./a.out
A::DerivedA constructor
B::DerivedB constructor
C::DerivedC constructor
D::DerivedD constructor
If you have a lot of classes, you'd usually choose a less brute force approach. A trie or hash_map between class names and factory functions is a good approach.
You can use a codegen approach as suggested by Greg to build this factory table, for example doxygen can parse your source code and output a list of all classes in xml format along with inheritance relationships, so you could easily find all classes deriving from a common "interface" base class.
It sounds like you might be using subclasses for things that should be encoded as fields.
Instead of coding the different behaviour in 100 classes, consider building a look-up table with rules/constants/function-pointers that allow you to implement the proper behaviour from one class.
For example, instead of:
class SmallRedSquare : public Shape {...};
class SmallBlueSquare : public Shape {...};
class SmallBlueCircle : public Shape {...};
class SmallRedCircle : public Shape {...};
class BigRedSquare : public Shape {...};
class BigBlueSquare : public Shape {...};
class BigBlueCircle : public Shape {...};
class BigRedCircle : public Shape {...};
try:
struct ShapeInfo
{
std::string type;
Size size;
Color color;
Form form;
};
class Shape
{
public:
Shape(std::string type) : info_(lookupInfoTable(type)) {}
void draw()
{
// Use info_ to draw shape properly.
}
private:
ShapeInfo* lookupInfoTable(std::string type) {info_ = ...;}
ShapeInfo* info_;
static ShapeInfo infoTable_[];
};
const ShapeInfo Shape::infoTable_[] =
{
{"SmallRedSquare", small, red, &drawSquare},
{"SmallBlueSquare", small, blue, &drawSquare},
{"SmallRedCircle", small, red, &drawCircle},
{"SmallBlueCircle", small, blue, &drawCircle},
{"BigRedSquare", big, red, &drawSquare},
{"BigBlueSquare", big, blue, &drawSquare},
{"BigBlueCircle", big, red, &drawCircle},
{"BigRedCircle", big, blue, &drawCircle}
}
int main()
{
Shape s1("SmallRedCircle");
Shape s2("BigBlueSquare");
s1.draw();
s2.draw();
}
This idea might not be applicable to your problem, but I figure it couldn't hurt to present it anyway. :-)
My idea is like the Replace Subclass with Fields refactoring, but I go a bit further.
You can abuse the preprocessor and set up some static class members that register your classes with a factory via a hash_map like Ben describes. If you have visual studio, look at how DECLARE_DYNCREATE is implemented in MFC. I've done something similar to implement a class factory. Non-standard for sure but since C++ does not offer any kind of support for this type of mechanism any solution is probably going be non-standard.
Edit
I said in a comment earlier I was working on documenting a scaled down version of something I had done. The scaled down version is still rather large so I posted it here. If there is enough interest I can copy/paste it on this site. Let me know.
This is the skeleton of a horrible, horrible way to do it:
class Factory {
public:
virtual Base * make() = 0;
};
template<typename T> class TemplateFactory : public Factory {
public:
virtual Base * make() {
return dynamic_cast<Base *>(new T());
}
};
map<string, Factory *> factories;
#define REGISTER(classname) factories[ #classname ] = new TemplateFactory<classname>()
Then call REGISTER(classname); for every relevant derived class of Base, and use factories["classname"]->make() to get a new object of type classname. Obvious flaws with the above code as written include massive potential for memory leaks, and the general awfulness of combining macros and templates.
Behold the mighty Boost.
The one thing you have to do in order to use my solution is to add a new member to all your classes, and that is a static const string that contains the name of the class. There are probably other ways to do it too, but that's what I have right now.
#include <iostream>
#include <vector>
#include <string>
#include <boost/fusion/container/list/cons.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/view/iterator_range.hpp>
using namespace std;
using boost::fusion::cons;
class Base { virtual void feed(){ } };
class Child1 : public Base{
void feed(){ }
public:
static const string name_;
};
const string Child1::name_ = "Child1";
class Child3 : public Base{
void feed(){ }
public:
static const string name_;
};
const string Child3::name_ = "Child3";
//...
class Child100 : public Base{
void feed(){ }
public:
static const string name_;
};
const string Child100::name_ = "Child100";
// This is probably the ugliest part, but I think it's worth it.
typedef cons<Child1, cons<Child3, cons<Child100> > > MyChildClasses;
typedef vector<Base*> Children;
typedef vector<string> Names;
struct CreateObjects{ // a.k.a convert_string_to_instance() in your example.
CreateObjects(Children& children, string name) : children_(&children), name_(name){ }
template <class T>
void operator()(T& cs) const{
if( name_ == cs.name_ ){
cout << "Created " << name_ << " object." << endl;
(*children_).push_back(new T);
}else{
cout << name_ << " does NOT match " << cs.name_ << endl;
}
}
Children* children_;
string name_;
};
int main(int argc, char* argv[]){
MyChildClasses myClasses;
Children children;
Names names;
names.push_back("Child1");
names.push_back("Child100");
names.push_back("Child1");
names.push_back("Child100");
// Extra test.
// string input;
// cout << "Enter a name of a child class" << endl;
// cin >> input;
// names.push_back(input);
using namespace boost::fusion;
using boost::fusion::begin;
using boost::fusion::for_each;
for(Names::iterator namesIt = names.begin(); namesIt != names.end(); ++namesIt){
// You have to know how many types there are in the cons at compile time.
// In this case I have 3; Child1, Child3, and Child100
boost::fusion::iterator_range<
result_of::advance_c<result_of::begin<MyChildClasses>::type, 0>::type,
result_of::advance_c<result_of::begin<MyChildClasses>::type, 3>::type
> it(advance_c<0 >(begin(myClasses)),
advance_c<3>(begin(myClasses)));
for_each(it, CreateObjects(children, *namesIt));
}
cout << children.size() << " objects created." << endl;
return 0;
}

How to create class objects dynamically?

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