Makng instance on "Heap" - c++

I have a class, called Ship() and it looks like this
class Ship()
{
public:
vector<Weapon*> Weapon
void AddWeapon(Weapon*)
}
void MyShip::AddWeapon(Weapon*)
{
Weapons.pushback(Weapon)
}
The Weapon class is an abstract base class, that must be derived from, for each type of weapon in the game. One of which is called Lazer
So in my code I can do:
int main()
{
Ship MyShip;
Lazer MyLazer;
MyShip.AddWeapon(&MyLazer)
}
How do I make sure the object pointed to by the vector in Weapons does not go out of scope? I believe the answer is making the instance on the heap but I don't know.

something like this is safest:
#include <memory>
#include <vector>
struct Weapon {
virtual ~Weapon() = default;
};
struct Lazer : Weapon {
};
class Ship
{
public:
void AddWeapon(std::unique_ptr<Weapon> weapon);
private:
std::vector<std::unique_ptr<Weapon>> _weapons;
};
void Ship::AddWeapon(std::unique_ptr<Weapon> weapon)
{
_weapons.push_back(std::move(weapon));
}
// test
using namespace std;
int main(){
auto ship = std::make_unique<Ship>();
ship->AddWeapon(std::make_unique<Lazer>());
return 0;
}

You should create weapon instance from heap using "new", then you can decide when to delete the instance you create. You also should use parent class pointer to point you instance, that's called dynamic binding.
int main()
{
Ship MyShip();
Weapon * p = new MyLazer();
MyShip.AddWeapon(p)
}

Related

Correct pattern for nested private class that inherit from outer class

I am trying to implement a pattern in C++ where a nested private class inherits from the outer class and the private class is instantiated via a static factory method in the outer abstract class.
I have this code now, that compiles, but I am not sure whether I did it correctly.
Search.h:
namespace ns_4thex {
class Search {
private:
class Implementation;
public:
static Search & create();
virtual int doIt() = 0;
};
class Search::Implementation: public Search {
int doIt();
};
}
Search.cpp:
#include "Search.h"
using namespace ns_4thex;
Search & Search::create() {
return *(new Search::Implementation());
}
int Search::Implementation::doIt() {
return 0;
}
Thought?
A static factory method always returns a pointer type. So the create function should return a pointer or smart pointers in modern c++.
The declaration:
static std::unique_ptr<Search> create();
The definition:
std::unique_ptr<Search> Search::create() {
return std::make_unique<Search::Implementation>();
}
The complete code may like this:
#include <memory>
namespace ns_4thex {
class Search {
private:
class Implementation;
public:
static std::unique_ptr<Search> create();
virtual int doIt() = 0;
};
class Search::Implementation : public Search {
int doIt();
};
std::unique_ptr<Search> Search::create() {
return std::make_unique<Search::Implementation>();
}
int Search::Implementation::doIt() { return 0; }
} // namespace ns_4thex
Your example has potentially a memory leak. The factory pattern should return a pointer type instead of the reference type. The caller using it can free the allocated memory
Search* Search::create() {
return new Search::Implementation();
}

How can I implement a vector<class> template's function?

I want to implement a template like this,
class animal{
}
class beast : public animal {
public:
beast(string name){}
void cry(){
cout<<"kuuuuu"<<endl;
}
}
int main(){
vector<animal*> a;
a.push_back(beast("tiger"))
vector[0].cry();
}
I want to implement similar to it. But my visualstudio cannot find the cry() function.
Please, how can I do it?
animal does not have a cry method. So you cannot call a cry on animal.
Also you have numerous syntax errors, which should give you errors before this line:
Your vector contains pointers and you are trying to stuff object itself inside.
To access member of object pointer points to, you should use ->, not ..
A lot of changes needed.static_cast is essential to call your cry method.
class definition should end with ;
Since you created vector<animal*>, you need to new the object before push back.
When you invoke the function cry , you need to static_cast it back to beast* and use -> instead . to invoke the cry function.
class animal{
};
class beast : public animal {
public:
beast(std::string name){}
void cry(){
std::cout<<"kuuuuu"<<std::endl;
}
};
int main(){
std::vector<animal*> a;
a.push_back(new beast("tiger"));
(static_cast<beast*>(a[0]))->cry();
}
#include <vector>
#include <iostream>
#include <string>
using namespace std;
class animal {
public:
virtual void cry() = 0; // declare public virtual cry method
};
class beast : public animal {
public:
beast(string name) {
}
void cry() {
cout << "kuuuuu" << endl;
}
};
int main() {
vector<animal*> a;
a.push_back(new beast("tiger")); // create new object and end with semicolon
a[0]->cry(); // use -> instead of . to call cry method of beast object pointed at
}

C++ Practice Vehicle Program Issues - Beginner Programming

I have made a little snippet of what my project is essentially based on - except much bigger. I am having a hard to grasping this particular concept. I need to make a car class which inherits the vehicle class and then there must be separate classes such as window, door, engine etc... I need to access those classes through the car class to adjust its "properties"
#include <iostream>
using namespace std;
class Vehicle
{
virtual void print() = 0;
};
class Car : public Vehicle
{
virtual void print();
Wheel tires[4];
};
class Wheel
{
public:
int pressure = 0;
int inflate(int psi)
{
pressure = pressure + psi;
}
};
int main()
{
//What would I have to put here or anywhere else to increase the pressure of a car object's FIRST tire's pressure - Car car1; car1.tires[0].inflate(10); (this doesn't seem to work)
}
#include <iostream>
#include <vector>
using namespace std;
class Vehicle
{
virtual void print() = 0;
};
class Car : public Vehicle
{
virtual void print();
Car(Wheel wheel[4])
{
}
};
class Wheel
{
public:
int pressure = 0;
int inflate(int psi)
{
pressure = pressure + psi;
}
};
int main()
{
Car car1(Wheel wheel[4]);
//I still don't know what I could add here that would inflate the first tire
}
The reason it doesn't work is that default access in a class is private (as opposed to structs, where it is public). With
class Vehicle
{
public:
virtual void print() = 0;
};
// Note that class Wheel has to be defined before class Car, or
// the compiler will complain that class Wheel is unknown here.
class Car : public Vehicle
{
public:
virtual void print();
Wheel tires[4];
};
it should be possible to write
int main() {
Car c;
c.tires[0].inflate(10);
}
Whether it is a good idea to have public data members is another question (it is not a good idea).
Would this work?
class Window
{
//...
};
class Car
: public Vehicle
{
std::vector<Windows> car_windows(5);
};
This is showing that a Car is-a Vehicle that contains 5 Windows.
This should be applied similarly for doors, engine, etc.
Wheel tires[4] will not create any Wheel objects, but just an array. That is why accessing it will not give you anything.
You need to have a Car constructor where you create the wheels of the car.
Also, print is a virtual pure function in Vehicle, so you need to implement it somewhere. Can have print() {}; or similar in your header file.
Or you can just use it to test/debug.
I am assuming you have working constructors.
Try something like this instead:
car1->tires[0]->inflate(10);

Is a big switch block unavoidable in C++ due to lack of reflection [duplicate]

This question already has answers here:
Is there a way to instantiate objects from a string holding their class name?
(12 answers)
Closed 9 years ago.
Assume I have a hierarchy of classes:
class Shape {
};
class Circle : public Shape {
}
class Square : public Shape {
}
... hundreds of other shapes continue on...
When given the name of a shape class as a string, I need to instantiate objects of that class.
In java, I can do something like this (pseudo code!)
Shape createShape(String name) {
return new Class.forName(name);
}
But in C++, I have to do this: (pseudo code!)
Shape * createShape(const string &name) {
if (name.compare("Circle") == 0) {
return new Circle();
}
else if (name.compare("Square") == 0) {
return new Square();
}
else if ... //hundreds of else if continues, one for each shape
}
Is there any better way in C++ to handle situation like this?
It's avoidable using the factory pattern, but you still need a bunch of boilerplate code to get off the ground. For example:
// Class factory functions -- these could also be inlined into their respective
// class definitions using a macro
Shape *createCircle() { return new Circle(); }
Shape *createSquare() { return new Square(); }
// etc.
// Create a map from type name to factory
typedef std::map<std::string, Shape *(*)()> ShapeFactoryMap;
ShapeFactoryMap factoryMap;
factoryMap["Circle"] = &createCircle;
factoryMap["Square"] = &createSquare;
// etc.
Then, when you want to instantiate an object, you can do this:
ShapeFactoryMap::iterator factory = factoryMap.find("Circle");
if (factory != factoryMap.end())
{
Shape *circle = factory->second(); // Creates a Circle instance
...
}
else
{
// Handle error
}
Whether this is better than just doing a series of if/else... string comparisons is not clear, since it depends on what exactly you're doing to be doing with this.
I second Adam Rosenfield's solution using maps. However, a lower level interface to get your higher level functionality is to use a dlsym() lookup.
Assume that your generic Shape interface lies in the file Shape.hpp and has the following form:
class Shape {
public:
virtual ~Shape () {}
//...virtual methods
virtual void draw () const = 0;
};
template <typename DERIVED>
class ShapeBridge : public Shape {
public:
static Shape * create () { return new DERIVED; }
};
struct ShapeFactory {
Shape * (*create) ();
};
Suppose you wanted to add a new shape dynamically by creating a new shared object, and then linking it dynamically into your existing running executable. Then, you can now create an abstract factory of sorts, which uses dynamic loading of shared objects to obtain the concrete factory functions:
#include <string>
#include <map>
#include <dlfcn.h>
struct ShapeCreator {
void *dlhandle_;
void *factory_;
ShapeCreator () : dlhandle_(0), factory_(0) {}
void open (std::string libname) {
dlhandle_ = dlopen(libname.c_str(), RTLD_LAZY);
factory_ = dlsym(dlhandle_, "factory");
}
void close () { if (dlhandle_) dlclose(dlhandle_); }
ShapeFactory * factory () const {
return static_cast<ShapeFactory *>(factory_);
}
static Shape * create (std::string name) {
static std::map<std::string, ShapeCreator> lookup;
static std::string dir = "./";
if (lookup[name].factory() == 0) {
lookup[name].open(dir + name + ".so");
}
return lookup[name].factory()->create();
}
};
Your shared object could have the following implementation:
// gcc -fPIC -shared -Wl,-export-dynamic -o Circle.so Circle.cpp -lc
#include "Shape.hpp"
#include <iostream>
class Circle : public ShapeBridge<Circle> {
public:
//..
void draw () const { std::cout << "I am a circle.\n"; }
};
extern "C" {
ShapeFactory factory = { Circle::create };
}
Then to dynamically create the shape:
Shape *s = ShapeCreator::create("Circle");
s->draw();
Of course, the example is a little more interesting if it actually obtained its name dynamically (like from a configuration file, or from a user input).
The main difference is that unlike Java, C++ doesn't have an in-built function like forName(String), which does the task for you. In C++ you have to implement it.
Now it's important how you do that stuff. The proposed way of switch/case is one way, which is straight forward but lengthy way. You can automate the things:
(1) First introduce an intermediate template class, which creates an object, so that you don't have to implement method for each and every class.
template<class Derived>
class ShapeCreator : public Shape { // This class automates the creations
public:
static Shape* Create () {
new Derived(); // Assuming that no-argument default constructor is avaialable
}
};
class Circle : public ShapeCreator<Circle> {
};
class Square : public ShapeCreator<Square> {
};
//... and so on
(2) Now inside the class Shape, introduce one static std::map, which holds a handle to every derived class.
class Shape {
public:
typedef std::map<std::sting, Shape* (*)()> ShapeMap;
static ShapeMap s_ShapeMap;
static Shape* Create (const std::string name) {
ShapeMap::iterator it = s_ShapeMap.find(name);
if(it == s_ShapeMap.end())
return 0;
it->second();
}
};
(3) Populating s_ShapeMap has to be done statically, you can choose to do it before the main() is called (be careful while doing this) or as the first function inside the main(). Use preprocessor trick to automate the things:
#define INIT(SHAPE) Shape::s_ShapeMap[#SHAPE] = &SHAPE::Create
Shape* InitializeShapeMap () {
INIT(Circle);
INIT(Square);
INIT(Triangle);
// ...
}
#undef INIT
Whenever any new shape is introduced, then just add it as an INIT inside the function.
C++ is a 'class based' language which means the structure of a class is only known at compile time. Hence you cannot generate a type at runtime.
It's better to avoid that sort of class instanciation unless you only know the class name at runtime.
If need to do that at large scale, have a look at third-party code generators such as jinja.
It'll help you create a factory off a template and a given mapping "string" -> "class name".
There's no way to do what you want the way it is in Java, but there are ways to make it slightly less painful than a giant switch statement. You will need some kind of factory. Personally I like to use something along these lines:
class ShapeBase
{
};
template<class TShape>
class Shape: public ShapeBase
{
public:
typedef TShape shape_type;
template< class TFactory >
static void registerClass(TFactory* factory)
{
factory->registerShape(shape_type::name(), [](){ return new shape_type(); });
}
};
class Circle: public Shape<Circle>
{
public:
static const char* name() { return "Circle"; }
};
class Square: public Shape<Square>
{
public:
static const char* name() { return "Square"; }
};
class ShapeFactory
{
private:
typedef std::function<ShapeBase*()> shape_creator;
std::map<std::string,shape_creator> _creators;
public:
ShapeFactory()
{
registerShapes();
}
void registerShapes()
{
Square::registerClass(this);
Circle::registerClass(this);
}
void registerShape( const std::string& name, shape_creator creator )
{
_creators[name] = creator;
}
ShapeBase* create(const std::string& name)
{
return _creators[name]();
}
};
int main( int argc, char** argv )
{
ShapeFactory factory;
ShapeBase* circle = factory.create("Circle");
ShapeBase* square = factory.create("Square");
return 0;
}
If you can get away with defining all of your Shape objects in an executable component or dynamic library, rather than a static library, then there are tricks that you can use to auto-register your classes with a singleton factory, but I think it's a better idea to do it this way and avoid the singleton.
There is no support for what you are asing in the language. Nevertheless you can use the following pattern to streamline your design:
class Shape
{
Shape *CreateShape(const char *name)
{
// Iterate single linked list of known derived classes.
Node *item = ListOfDerivedClasses;
while (item != NULL)
{
if (strcmp(item->name, name) == 0)
return item->factory();
item = item->next;
}
}
typedef Shape *CreateShapeInstance();
struct Node
{
char *name;
CreateShapeInstance *factory;
Node *next;
Node(char *n, CreateShapeInstance *f)
{
name = n; factory = f;
next = Shape::ListOfDerivedClasses;
Shape::ListOfDerivedClasses = this;
}
};
static Node *ListOfDerivedClasses;
};
class Circle : public Shape
{
static Shape *CreateInstance() { return new Circle(); }
}
static Shape::Node circle_info("Circle", Circle::CreateInstance);
The idea is that the single linked list that contains only static elements is created during initialization of static objects and it is never modified after that. This design allows adding derived classes without modifying the base class while CreateShape in the base class can create any derived class that registered itself in the list.

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;
}