This question already has answers here:
What are forward declarations in C++?
(8 answers)
Closed 2 years ago.
I'm trying to implement something along the lines of:
Class EntityManager
{
AddEntity(Entity e);
RemoveEntity(Entity e);
std::vector<Entity> entities;
}
Class Entity
{
// Need a mechanism here to add and remove entities on the constructor and destructor of Entity
}
Hope this makes sense. Eventually Entity will contain a number of pure virtuals, when I inherit from Entity I want it to automatically add the entity to the vector, the EntityManager will then call the pure virtual functions on each entity.
Thanks for your time.
If you're using virtual functions you need pointers, so Entity* is your base type here, or perhaps one wrapped in a smart pointer.
When you use Entity you're saying "these elements are all literally Entity and are exactly the same size" while Entity-derived classes may be quite different and significantly larger.
As a pointer there's no size information baked in, that's all a function of how it was allocated, which is typically via new with the correct class called.
If you want to automatically add these to something as they're created then you need to add code to your base class constructor.
So long as the adding code is in the .cpp implementation of Entity then there's no circular references problem. Declare Entity first and the EntityManager knows enough to build on.
Related
I'm fairly new to c++ templates.
I have a class whose constructor takes two arguments. It's a class that keeps a list of data -- it's actually a list of moves in a chess program.
I need to keep my original class as it's used in other places, but I now need to pass extra arguments to the class, and in doing so have a few extra private data members and specialize only one of the private methods -- everything else will stay the same. I don't think a derived class helps me here, as they aren't going to be similar objects, and also the private methods are called by the constructor and it will call the virtual method of the base class -- not the derived method.
So I guess templates are going to be my answer. Just looking for any hints about how might proceed.
Thanks in advance
Your guess is wrong. Templates are no more the answer for your problem than inheritance is.
As jtbandes said in comment below your question, use composition.
Create another class that contains an instance of your existing class as a member. Forward or delegate operations to that contained object as needed (i.e. a member function in your new class calls member functions of the contained object). Add other members as needed, and operations to work with them.
Write your new code to interact with the new class. When your new code needs to interact with your old code, pass the contained object (or a reference or a pointer to it) as needed.
You might choose to implement the container as a template, but that is an implementation choice, and depends on how you wish to reuse your container.
Templates are used when you want to pass at compile time parameter like values,typenames, or classes. Templates are used when you want to use exactly the same class with the same methods, but applying it to different parameters. The case you described is not this I think.
If they aren't goign to be similar objects you may want to create a specialized class (or collections of function) to use from the various other classes.
Moreover you can think of creating a base class and extending it as needed. Using a virtual private method should allow you to select the method implementation of the object at runtime instead of the method of the base class.
We may help you more if you specify what does they need to share, what does your classes have in common?
The bare bones of my present code looks like this:
class move_list{
public:
move_list(const position& pos, unsigned char ply):pos_(pos),ply_(ply){
//Calculates moves and calls add_moves(ply,target_bitboard,flags) for each move
}
//Some access functions etc...
private:
//private variables
void add_moves(char,Bitboard,movflags);
};
Add_moves places the moves on a vector in no particular order as they are generated. My new class however, is exactly the same except it requires extra data:
move_list(const position& pos, unsigned char ply,trans_table& TT,killers& kill,history& hist):pos_(pos),ply_(ply),TT_(TT),kill_(kill),hist_(hist) {
and the function add_moves needs to be changed to use the extra data to place the moves in order as it receives them. Everything else is the same. I guess I could just write an extra method to sort the list after they have all been generated, but from previous experience, sorting the list as it receives it has been quicker.
I cannot understand the implementation of inheritance in Google's V8 JavaScript engine. It clearly (?) implements an inheritance hierarchy, but seems to completely do away with virtual functions.
This is the inheritance hierarchy as detailed in the objects.h header file:
// Inheritance hierarchy:
// - Object
// - Smi (immediate small integer)
// - HeapObject (superclass for everything allocated in the heap)
// - JSReceiver (suitable for property access)
// - JSObject
// - JSArray
// ... and many more entries
Most object types are derived from Object, which is declared as follows:
// Object is the abstract superclass for all classes in the
// object hierarchy.
// Object does not use any virtual functions to avoid the
// allocation of the C++ vtable.
// Since both Smi and HeapObject are subclasses of Object no
// data members can be present in Object.
class Object {
// ... bunch of method declarations and definitions
};
The relatively simple Smi class is declared next:
class Smi: public Object {
public:
// methods declarations and static member definitions
};
and so on.
For the life of me, I cannot understand how can, say, an instance of Smi can be used as an Object; there are no virtual functions and I cannot find overrides in the the implementation file, objects.cc. At 17,290 lines, though, trying to understand what is going on is proving a difficult task.
As another difficulty, I found an ObjectVisitor class in the same header file (this one is more classical; it consists of virtual methods). But I could not find the equivalent Accept(Visitor*) (or similar) method in the Object base class.
What I am asking in concrete is for a minimal example that illustrates how does this inheritance pattern works.
The classes in objects.h do not actually define real C++ classes. They do not have any fields. The classes are merely facades to objects managed on the V8 JavaScript heap. Hence they cannot have any virtual functions either, because that would require putting vtable pointers into the JS heap. Instead, all dispatch is done manually, via explicit type checks and down casts.
The this pointer inside methods isn't real either. For smis, this is simply an integer. For everything else it is a pointer into the V8 heap, off by one for tagging. Any actual accessor method masks this pointer and adds an offset to access the appropriate address in the heap. The offsets of each field is also defined manually in the classes.
Take a look at Object::IsPromise() for a perfect example of how it works:
bool Object::IsPromise(Handle<Object> object) {
if (!object->IsJSObject()) return false;
auto js_object = Handle<JSObject>::cast(object);
// Promises can't have access checks.
if (js_object->map()->is_access_check_needed()) return false;
auto isolate = js_object->GetIsolate();
// TODO(dcarney): this should just be read from the symbol registry so as not
// to be context dependent.
auto key = isolate->promise_status();
// Shouldn't be possible to throw here.
return JSObject::HasRealNamedProperty(js_object, key).FromJust();
}
The way inheritance is used here is static. That is, type queries are done by a proxy or container (using some hidden magic, that, at a glance looks like they're using references to query a tag), and conversions from Object to a derived class is done by static_cast<>(). In that way, the member functions of the derived class can be called.
Note that in the above function, the type query and cast is indirectly performed by the Handle<> class, not by Object or any of its derived classes.
Note also that the functions which accept ObjectVisitor as a parameter are rather uniformly called Iterate, and that these functions all appear on proxies or handles.
I am designing and entity-component system for a project, and C++ memory management is giving me a few issues. I just want to make sure my design is legitimate.
So to start I have an Entity class which stores a vector of Components:
class Entity
{
private:
std::vector<std::unique_ptr<Component> > components;
public:
Entity() { };
void AddComponent(Component* component)
{
this -> components.push_back(std::unique_ptr<Component>(component));
}
~Entity();
};
Which if I am not mistaken means that when the destructor is called (even the default, compiler created one), the destructor for the Entity, will call ~components, which will call ~std::unique_ptr for each element in the vector, and lead to the destruction of each Component, which is what I want.
The component class has virtual methods, but the important part is its constructor:
Component::Component(Entity parent)
{
parent.addComponent(this) // I am not sure if this would work like I expect
// Other things here
}
As long as passing this to the method works, this also does what I want. My confusion is in the factory. What I want to do is something along the lines of:
std::shared_ptr<Entity> createEntity()
{
std::shared_ptr<Entity> entityPtr(new Entity());
new Component(*parent);
// Initialize more, and other types of Components
return entityPtr;
}
Now, I believe that this setup will leave the ownership of the Component in the hands of its Parent Entity, which is what I want. First a small question, do I need to pass the entity into the Component constructor by reference or pointer or something? If I understand C++, it would pass by value, which means it gets copied, and the copied entity would die at the end of the constructor.
The second, and main question is that code based on this sample will not compile. The complete error is too large to print here, however I think I know somewhat of what is going on. The compiler's error says I can't delete an incomplete type. My Component class has a purely virtual destructor with an implementation:
inline Component::~Component() { };
at the end of the header. However since the whole point is that Component is actually an interface. I know from here that a complete type is required for unique_ptr destruction. The question is, how do I work around this? For reference I am using gcc 4.4.6.
Component::Component(Entity parent)
takes parent by calue so you add the component to this temporary, that will go away at end of function. And the original will miss this call. try
Component::Component(Entity &parent)
For the other part, you must ensure the type is complete where the template is instantiated.
The usual way is to declare the dtor in class as you do, and just put the implementation in the .cpp where the required types are defined. Inline is not really necessary.
Or you could include the other header before Entity, if in will not cause circular includes.
This question already has answers here:
Why is a class allowed to have a static member of itself, but not a non-static member?
(2 answers)
Closed 8 years ago.
How can I make an instance of a class inside its definition?
class Test{
Test _test;
};
This throws
error: field _test has incomplete type
Using a pointer works but I would like to avoid using a pointer if possible.
Just imagine you could do something like that: this would be a recursive definition. An object of type Test contains an object of type Test, which contains an object of type Test, and so on without a termination until you or your compiler go crazy.
I don't really think you would want anything like that, even if it compiled. Using pointers, on the other hand, is OK for two reasons:
A pointer could by null, thus breaking the otherwise infinitely recursive chain of Test objects (which would take infinite space at run-time);
A pointer has fixed size, so the compiler doesn't need to compute the size of Test in order to compute the size of Test itself (leading to infinite recursion at compile-time).
Using a pointer works but I would like to avoid using a pointer if possible.
If you are worried about manual memory management, just use a smart pointer:
#include <memory>
class Test
{
std::unique_ptr<Test> _test;
};
Answer this question: how big would your class be?
The only two solutions I can think of is either by using a pointer:
class Test
{
public:
Test * data;
};
This solution is common in advanced structures, such as lists or trees.
Another way is to declare the internal field as static:
class Test
{
public:
Test(int i);
static Test data;
}
Test Test::data = Test(5);
This solution is common for singletons, multitons or similar structures. Notice though, that you can access the field only from the class, not from its instance:
Test test = Test::data;
Your Test is not yet defined completed so how come you create its instance. Sure you can create pointer. Because pointer is incomplete type.
That is why Singleton class and link list have pointers to their reference and not complete object itself.
The memory for the class variables is initialized when an object of the class is made. But if one makes the object of the class in its definition only then during that point the compiler will not be able to initialize the variable of the class as at that point the definition of the class is yet not completed.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have taken several classes now in C++ and a little bit of python. And a common thing that keeps coming up is my failure to really understand whats going on when you are creating a class. I was wondering if someone could either explain the specifics as far as classes in C++ are concerned or least point me to websites that go into great detail. I know the declaration but as far as what is going on with accessors, methods, constructors and destructors and even if you'd like to go as far as define when and why would the best time to use a class. I just need overall clarification. Thanks!
In programming, you have data and functions that manipulate that data. A structure (struct) allows you to group related pieces of data into one logical object.
A class allows you to group data and functions together as a single unit. Thus, instead of saying matrix_add(m1, m2), you can say m1.add(m2). The data and functions can be private (only accessible to the class), protected (accessible to the class and its children) or public (accessible to anyone). This is called encapsulation: typically, the data is private and is accessible via a set of public functions. In C++, a struct defaults to public scope and a class to private scope, but are otherwise identical.
An accessor is the name of a function that typically provides acccess to the private data of a class. These can be getters that return (or get) the data, or setters that modify (or set) the data. Typically, these methods check the input for validity to ensure internal constraints hold. Note that an accessor may not directly return private data, but derived properties; that is, size and empty on C++ containers (vector, list, ...) could be thought of as accessors even though these could be computed values.
A constructor is a special function that allows the class to initialize the data to sane values, or allow the user to create a new object of the class with potentially different data. For example, a rectangle class could be constructed from another rectangle, a point and size, a set of top/left/bottom/right values or could be empty. In C++, the constructor has the same name as the class; in python this is called __init__.
A default constructor is a constructor that takes no parameters and initializes the class to its default state (e.g. an identity matrix for a matrix class).
A copy constructor is a constructor that takes another object of the class type and creates a copy of it. This allows allocated memory to be handled properly (e.g. for string and vector classes). With a simple data structure the objects are copied by value, so the two objects would reference the same memory.
A destructor is a special function that allows the class to perform cleanup. This could be things like deleting any allocated memory, releasing locks on mutexes or closing open file handles. In C++, a destructor has the same name as the class but with a ~ in front of it, e.g. for a matrix class the destructor would be ~matrix.
A method is just a function that is a part of a class. Each method takes the class object being operated on as the first parameter. When declaring methods, C++ does this internally for you (providing an implicit this argument) while python requires you to provide the parameter explicitly.
In C++, an operator is a special function that is used to implement e.g. +, -, * and /. This allows you to create classes that can be used like built in types (esp. for mathematical classes like vectors, matrices, complex and rational numbers).
A class (the "derived" class) can inherit from another class (the "base" class). Here, the derived class is a child of the base class and can access any protected data or methods. This is called inheritance. These form a class heirarchy.
A class can be constructed to have virtual methods that can be overriden by derived classes. This is called polymorphism.
You can declare virtual methods that do not provide any implementation. These methods are called pure virtual methods and the classes that provide them are known as abstract base classes. Here, the derived class needs to implement these methods, while with non-pure virtual methods the derived class does not need to implement the method.
A class that only has pure virtual methods (no other methods) is effectively an interface class. C++ does not have any special notation for this, whereas other languages do.
Interfaces are typically used to interact between two or more different systems. For example, a music player could provide a plugin architecture that allows plugins to extend the supported audio formats it can handle. Here, the interface(s) provide the contract between the player and plugin.
Think of objects as "smart" structures which not just contain data but also the code to manipulate that data. Think of classes as type definitions for these "smart" structures.
Creating a class instance is just like creating a variable of a structure type. Calling a member function of a class is just like calling a normal function, and passing the structure to it as a parameter with the name "this".
When you understood this, you already understand most about what object-oriented programming is all about.
By the way: Do you know what's the difference between the keywords struct and class in C++? In a struct, all members are public by default and in a class all members are private by default. That's it. Otherwise structs and classes are the same thing. When you explicitely declare all members as private, public or protected, you can switch them out and the program will compile and work just like before.
And a common thing that keeps coming up is my failure to really understand whats going on when you are creating a class.
I'm answering this part as others have answered the second part, code below is java however, looking at the code kindly give importance to class concept than Java constructs.
Well, before jumping into the CLASS thing in the programming world. Lets take a look a the real world. If we look around us we see many elements [rocks, animals, humans, plants etc] in our living echo system. Careful observation finds that, they have some common features that can be grouped together [Life, Organs, Color etc] , lets call this common grouping by a technical name called "CLASS".
In order to understand, classes in programming world one should understand why there is such a construct called class. Main fact is the it is part of a programming paradigm called Object Oriented Programming, where, programmers try to map real world objects say Vehicles, Banks, etc into programming models called Objects. In order to create these object, we have to create a construct that can actually describe those objects. Such a construct is called a class.
Below explanations goes beyond just Classes for completeness.
Lets look at a technical example Circle, Rectangle, Square, Hexagon, looking at them we find that they belong to a common CLASS called SHAPE.
Don't get carried away by details [extends, #Override etc] in the example below. It explains simple concept of classing how it is exploited to make new classes. Once a class is created, it is just a skeleton ie it is not allocated any memory for a real use. In order to make a class useful, we create its objects. So objects are 'elements' with different states for same class.
Say for circle objects, obj1, obj2, each object have different radius.
class Shape {
String name;
int color;
public Shape(String name, int color) {
this.name = name;
this.color = color;
}
String getName() {
return name;
}
int getColor() {
return color;
}
double getArea() {
return 0;
}
double getPerimeter() {
return 0;
}
}
class Rectangle extends Shape {
int l, b;
public Rectangle(int l, int b, int h, int color) {
super("Rectangle", color);
this.l = l;
this.b = b;
}
/* Overloading */
#Override
double getArea() {
return l*b;
}
/* Overloading */
#Override
double getPerimeter() {
return (2*l + 2*b);
}
}
class Circle extends Shape {
int r;
public Circle(int r, int color) {
super("Circle", color);
this.r = r;
}
dobule getArea() {
return (PI * (r*r));
}
double getPerimeter() {
return (2*PI*r);
}
}