In these days I'm starting to get my feet wet with c++ and, due to my Java-ish background, I obviously have some problems in understanding some c++ features.
Since java offers only references and primitives one of the most mysterious c++ feature for me is non-pointer (and non-primitive) fields.
Here is an example of what I mean.
If I should write a c++ implementation in c++ of a list of objects of type X I would write something like:
class XList{
private:
struct node {
X* data;
node* next;
};
node* first;
public:
*/
a lot of methods
*/
}
This code is probably awful, I know about templates, STL and whatnot but the problem for me here is just the field "data". If a declare "data" as a X pointer I presume that I can use it in a way very similar to Java references.
What could be instead the reason to declare data as a X (X data;). What is the difference? I know the difference between allocating on the stack and on the heap but is there any connection here?
Please help me get a bit more of a grip on this topic.
Thank you.
--- UPDATE: ----
Most of the answers seem to focus on the difference between using the plain type on a pointer in general.
Probably I wrote the question in the wrong way, but I already know the difference between allocating on the stack or on the heap (the basics at least).
What I can't understand is that in my (probably wrong) opinion the usage of a plain type in a member variables (not field, thank you for your correction) should be just some kind of corner case. Especially when templates are involved a copy of the data makes no sense to me.
Instead every time I see an implementation of some data structure the plain type is used.
E.g.: If you search "bst c++ template" on google you will find a lot of implementation like this one:
template<class T>
class BinarySearchTree
{
private:
struct tree_node
{
tree_node* left;
tree_node* right;
T data;
};
tree_node* root;
public:
/*
methods, methods and methods
*/
};
Do you really want to make a copy of every data of type T inserted on this tree without knowing its size? Since I'm new to the language I suppose that I misunderstood something.
The advantage of using an X instead of an X * is that with the pointer, you have to allocate the space for the X as well, which uses more space (4 bytes or 8 bytes for the pointer, plus the overhead of the allocation for the X via new), whereas with the plain type, you avoid that overhead. So, it is simpler just to use the plain X.
You'd use the pointer when you definitively do not want to make a copy of the X value, but you could end up with dangling pointers if you are not careful. You'd also use the pointer if there are circumstances where you might not have an object to point to.
Summary
Use the direct object to simplify memory management.
Use the pointer when you cannot afford copying or need to represent the absence of a value.
The difference is that a pointer points to an as yet allocated or determined hunk of memory. But when you leave off the *, you're saying "allocated space for this entire class (not just a pointer to a class) along with this class."
The former, using a pointer, puts all the memory allocation and maintenance in your hands. The latter just gives you the object as a member of your class.
The former doesn't use much space (what, four to eight bytes, depending on architecture?) The latter can use a little up to a LOT depending on what the class X has as its member.
I use non-pointer data members when: 1) I'm sure this data shouldn't and won't be shared among objects 2) I can rely on automatic deallocation when the oject is finally destroyed. A good example is a wrapper (of something to be wrapped):
class Wrapper
{
private:
Wrapped _wrapped;
public:
Wrapper(args) : _wrapped(args) { }
}
The primary difference is that if you declare an X* you're responsible for memory management (new and delete) on the heap, while with an X the memory is handled on the stack, so it's allocated/freed with the scope.
There are other subtle things as well, like worrying about assignment to self, etc.
Related
thanks in advance for any help you can give. I am struggling with figuring out what exactly goes into a destructor because I haven't found a great explanation of really how you implement the idea with code. My textbooks and a couple of different things I've read explain that a destructor is essentially a method that is called for an abstract data type (ADT) that helps to release any resources/memory used by an ADT object. My textbook code example though literally just has a cout statement inside of the destructor that says "The object is about to be destroyed" which you can imagine isn't particularly helpful.
I am working on a stacks project where we're creating a stack of pointers to a struct object called Data (which does not have a destructor, read a little bit about why that is earlier) which contains two attributes: int ID and string data. Then the stack itself only has two attributes: int top (holds the top value for peek and pop functions) and the array of Data pointers.
So do I need to delete top and delete the stack of pointers? Can I just delete the stack of pointers as a whole or do I need to iterate through the stack and delete everything inside of it before deleting the stack array itself? If I do need to delete each pointer, can I just delete the pointer? Or do I need to figure out how to also delete the information that is inside of that memory location where the pointer is pointing? And do I do all of those things using the delete keyword?
Just trying to wrap my head around what all I need to specifically target when deleting things in the destructor. Once I know that much, I think that I can figure out how to do the actual writing by googling for syntax and testing out in the IDE/terminal, double checking things with the professor if syntax isn't quite working, etc.
Normally I'd ask these things to my professor in class, but the class itself is for data structures and algorithms so I don't want to interrupt those topics to ask something that feels sort of regressive. I think maybe these things were supposed to be covered in the prerequisite course but I took that class a while ago and it doesn't seem that these things were really covered well based on that textbook I still have (and there was no lecture because it was online).
I really want to learn these concepts deeply and understand the architecture behind them as much as possible so that I'm prepared well for writing good code and working in a professional environment. Thank you again for any help you all can give!
To requote your questions:
So do I need to delete top and delete the stack of pointers? Can I just delete the stack of pointers as a whole or do I need to iterate through the stack and delete everything inside of it before deleting the stack array itself? If I do need to delete each pointer, can I just delete the pointer?
That really depends on how you implemented your array of pointers, if each pointer has is not pointing to another array, list, or some object of some kind, and given your array is a static array then, simply typing delete arrayName[] is fine. But if your pointers point to another array or list or object of some kind, then you would need to set variables for those objects or list or array to their default values and delete them one by one.
Here are the three ways to write a destructor for an abstract class:
The class may be deleted polymorphically:
class BaseClass
{
public:
virtual ~BaseClass() = default;
};
The class may be used polymorphically, but deletion always uses the exact runtime type (e.g. std::make_shared() acts this way)
class BaseClass
{
protected:
/* not virtual */ ~BaseClass() = default;
};
The class is just a fancy namespace (namespaces are missing some features) and is used as a container but never instantiated:
template<stuff> class FancyNameSpace
{
private:
/* virtual doesn't matter */ ~FancyNamespace() = delete;
};
A class hierarchy should always be using the compiler-generated default destructor, with only changing the access and virtualness. That's because acting as a base class is a separate responsibility from managing a resource, so the Single Responsibility Principle says that the resource management should be moved to a helper class whose sole function is scope-based resource management (RAII).
The title of this question is pretty convoluted, so I'll try to frame it with an example. Let's say that I have an abstract base class, with a number of classes which inherit from it. In the example below I've only shown two inherited classes, but in reality there could be more.
class Base {
public:
Base();
virtual ~Base() = 0;
/// Other methods/members
};
class SmallChild: public Base {
public:
SmallChild();
~SmallChild();
/// Other methods/members such that sizeof(SmallChild) < sizeof(LargeChild)
};
class LargeChild : public Base {
public:
LargeChild();
~LargeChild();
/// Other methods/members such that sizeof(LargeChild) > sizeof(SmallChild)
};
I need to implement a container which stores up to N inherited objects. These objects need to be created/destroyed at runtime and placed in the container, but due to constraints in the project (specifically that it's on embedded hardware), dynamic memory allocation isn't an option. The container needs to have all of its space statically allocated. Also, C++11 is not supported by the compiler.
There was only one way I could think to implement this. To reference the N objects, I'd first need to create an array of pointers to the base class, and then to actually store the objects, I'd need to create a buffer large enough to store N copies of the largest inherited object, which in this case is LargeChild
Base * children[N];
uint8_t childBuffer[N * sizeof(LargeChild)];
I could then distribute the pointers in children across childBuffer, each separated by sizeof(LargeChild). As objects need to be created, C++'s "placement new" could be used to place them at the specified locations in the array. I'd need to keep track of the type of each object in childBuffer in order to dereference the pointers in children, but this shouldn't be too bad.
I have a few questions regarding this entire setup/implementation:
Is this a good approach to solving the problem as I've described it? I've never implemented ANYTHING like this before, so I have no idea if I'm way out to lunch here and there's a much easier way to accomplish this.
How much of this can be done at compile-time? If I have M types of inherited classes (SmallChild, LargeChild, etc.) but I don't know their size in relation to each other, how can I determine the size of childBuffer? This size depends on the size of the largest class, but is there a way to determine this size at compile-time? I can imagine some preprocessor macros iterating through the classes, evaluating sizeof and finding the maximum, but I have very little experience with this level of preprocessor work and have no idea what this would look like. I can also imagine this being possible using templates, but again, I don't have any experience with compile-time template sorcery so I'm only basing this on my intuition. Any direction on how to implement this would be appreciated.
Do you need to be able to dealocate the objects? If not, it may be easier to override operator new. I refer to this:
void* operator new (std::size_t size) throw (std::bad_alloc);
All your overrides would allocate memory from a sinle large buffer. How much memory to allocate is specified by the size parammeter.
This way you should be able to just say
children[i] = new SmallChild();
Edit: if you do need to deallocate, you need more complex data structures. You may end up re-implementing the heap anyway.
If the set of objects is fully static (set at build time and doesn't change at runtime), the usual approach is to use a set of arrays of each derived class and build up the 'global' array with pointers into the other arrays:
static SmallChild small_children[] = {
{ ...initializer for first small child... },
{ ...initializer for second small child... },
...
};
static LargeChild large_children[] = {
{ ...initializer for first large child... },
...
};
Base *children[N] = { &small_children[0], &small_children[1], &large_children[0], ....
This can be tricky to maintain if there are children being added/removed from the build frequently, or if the order in the children array is important. It may be desirable to generate the above source file with a script or build program that reads a description of the children needed.
Your approach is interesting, given your constraints (i.e. no use of dynamic allocation).
In fact you are managing on your own way a kind of array of union anyChild { smallChild o1; largeChild o2; ... }; The sizeof(anyChild) would give you the largest block size you are looking for.
By the way, there could be a risk of dangling pointers in you approach, as long as all objects have not been created with the the placement new, or if some of them are deleted through explicit call of their destructor.
if you put your derived types into a union:
union Child{
SmallChild asSmallChild;
LargeChild asLargeChild;
}
Then the union will automatically be of the sizeof the largest type. Of course, now you have a new problem. What type is represented in the union? You could give yourself a hint in the base Class, or you could instead make Child a struct which contains a hint and then the union inlined within. For examples look at components made by Espressif for ESP32 on the githubs, lots of good union uses there.
Anyways, when you go to allocate, if you allocate an array of the union'ed type it will make an array of largest children... because that's what unions do.
I've been coding in C++ and I was wondering if someone could help me with the general reason why we sometimes need to make pointers to class members and other times we don't.
For example if we are coding a Binary Tree
I implement it as
class BinaryTree{
BinaryTree * left;
BinaryTree * right;
int val;
public:
BinaryTree(int v) {left = NULL; right = NULL; val = v;}
//implementation of any other neccessary functions
};
I use the BinaryTree pointers to left and right, because we can't do it without the pointer since BinaryTree does not exist at that point in time.
Are there any other reasons to do this? Is there anyway around this?
Also, if we put pointer member functions, will the implicit destructor handle the deletion of them?
Thanks for your time.
This is a box:
it has a volume of about one cubic meter, so it can only store objects that have total volume of one cubic meter. And it definitely can't store two identical boxes as itself. Note that each one of these two boxes would also need to contain two boxes like it, and so on, and so on.
This is a struct:
struct BinaryTree {
BinaryTree left;
BinaryTree right;
int val;
};
it has a finite size equal to sizeof(BinaryTree), so it can only store objects that have total size less or equal to sizeof(BinaryTree). And it definitely can't store two values of type BinaryTree. Note that each one of these two values would also need to store two values like it, and so on, and so on.
Since the struct instances can't contain other instances of the same struct, and we need to define relations between them, and trees are definitely hierarchical, we use pointers here.
Note that the only thing that so called raw pointer to T (that is, T*) does, is to point to T. Since pointing is the only task of such pointer, destruction won't destroy the pointed object, only the pointer.
There exist types that behave like pointers, but also do other tasks, like managing lifetime of pointed object. These are C++11's std::unique_ptr, and std::shared_ptr, and many others. I highly recommend using them.
Objects often hold members that only need to be created based on run time conditions or parameters. You want to delay creation as late as possible. This is a common case for using pointers.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I know the difference between the points-to (->) and dot (.) operator but I don't see why the need for the two arrises? Isn't it always just as easy not to use pointers and just use the dot operator? From http://www.programcreek.com/2011/01/an-example-of-c-dot-and-arrow-usage/
#include <iostream>
using namespace std;
class Car
{
public:
int number;
void Create()
{
cout << "Car created, number is: " << number << "\n" ;
}
};
int main() {
Car x;
// declares x to be a Car object value,
// initialized using the default constructor
// this very different with Java syntax Car x = new Car();
x.number = 123;
x.Create();
Car *y; // declare y as a pointer which points to a Car object
y = &x; // assign x's address to the pointer y
(*y).Create(); // *y is object
y->Create();
y->number = 456; // this is equal to (*y).number = 456;
y->Create();
}
Why ever bother using pointers? Just create Y as X was, it would work the same. If you say you need pointers for dynamically alocated memory, then why bother having the dot operator?
I think you're mixing two separate concerns.
First, the -> operator is unnecessary, yes. x->y is equivalent to (*x).y, but the -> operator is easier to type, so it's basically just a convenience.
The second part is whether to use pointers at all.
And you're right, often you shouldn't. By default, just create your objects then and there, and refer to them direclty:
Foo bar;
bar.baz():
but pointers are still necessary for a lot of cases. Objects need to be able to reference other objects. A reference can do that, but it can't be reseated. Once it is initialized, it will always point to the same object.
A pointer can be updated to point to a different object.
Linked lists, tree data structures and countless other things depend on objects being able to point to other objects.
So yes, we need pointers. But we don't need the -> operator. We just use it because it's convenient.
a. it just makes it easier to semantically understand the code without looking at the types, or having special notations like m_pszMyName. You can instantly tell reading the code what is a pointer and what is a value.
b. Think of the case of shared_ptr and overriding operators. shared_ptr<T>->get() means something else than shared_ptr<T>.get(). The first being the function in a pointed object, the second one being the function of the shared_ptr class itself. This is just one example, but you see the point.
From your link:
The following example should be a good one.
It is actually a bit confusing. Why would you ever create an object on the stack (Car x;) and then create a pointer to it to access it using ->?
Instead of trying to answer the implied question "Why do we need pointers?" I'll try to clear up any confusion that might have arisen from that example.
In your comment you say:
I'm wondering if there's a difference between objects that are created differently.
In the example there is only one object, the Car on the stack created by Car x; (to be complete there is also a Car-pointer on the stack, created by Car *y;). They go out of scope when main() exits, so their memory gets cleaned up.
But there is another way to create objects, which I guess you already know about based on your comment, and this is to use new to initialize them on the heap: Car *z = new Car;. Objects on the heap will never go out of scope, so you can keep using them after the function that called new exited, but you have to explicitly clean them up using delete to prevent memory leaks.
So there it is, a more realistic use of a pointer to an object: the return value of new.
Isn't it always just as easy not to use pointers and just use the dot
operator?
C/C++ like other higher order languages do not encapsulate the pointers with some sugar coating syntax. Pointer's arise naturally and the list below is not exhaustive
Allocating memory from heap. Static data allocation, or allocating storage in stack is always not feasible. There are overheads with transfer of ownership, space constraint and dynamic nature of your program.
Reading and writing files.
Iterating over objects including C-Type string. You can use array access syntax, but there is little safety difference and arrays are degenerated to pointers when you pass to a function(size information is lost).
All the above can be encapsulated into objects when you thing from C++ perspective.
FILE IO through iotream
pointers through smart pointers(some from the C++98 and some in C++11 or eve boost)
Iterators for STL Type Objects.
Using reference
Nevertheless, Pointers are there even in languages where you don't see them explicitly. They are just encapsulated to higher order objects.
This explains to some extent why we can't think beyond pointers, the next part probably you are interested is in the syntax. Why do we atall need ptr->somemember instead of (*ptr).somemember.
Its just shorthand for a repetitive usage. C/C++ programmers have got used to it and I have not seen till to date a single program using the superfluous syntax.
-> is just for short. Consider a class represent nodes of trees:
struct node {
int data;
node* left;
node* right;
};
The member left is a pointer point to the left child of the node. Suppose we have a pointer to some node p, now we want to get the pointer point to the right child of the left child of the left child of p, using dot we have to write (*(*(*p).left).left).right, difficult to read and error-prone, using -> we can simply write p->left->left->right, very clear.
The existence of both -> and . operators in C++ is a direct influence from C. C makes the distinction between accessing an object through a pointer and accessing an object which is declared in the current scope.
In C++ references are a natural extension of accessing locally scoped objects.
I don't know whether the creators of C considered this, but I always used to use it as a small optimisation guide. Looking at a piece of code, you could see that -> would calculate the final address at runtime, whereas the . operator would calculate the address at compile time. This even works when accessing members of structures. Consider the following: myptr->mMember.mValue The offset from mMember to mValue can be calculated at compile time, whereas the final address calculation from the pointer must be calculated at run time. A minor consideration as far as optimisation is concerned these days, I'll admit, and with references in C++ it's no longer possible to do this, but 20 years ago it was something to bear in mind.
Yes, you could always use (*x).member instead of x->member, but would you really want to when x is a complex expression?
Having related things (* and . in this case) far away makes the source code less readable, so having the -> "in one place" is simply a nicer syntax.
As for the need for the concept of pointers, there are 2 main reasons:
1. Object Lifetime
There are two ways to allocate an object
On the stack.
In the dynamic memory.
The stack winds and unwinds as the flow of execution enters and exits functions, so the lifetime of a stack object is inevitably married to how long we stay in the function that created it.
If you need an object that lives longer than the function that created it, you need to create it in the dynamic memory, and the only way to identify such object is by its memory address, aka. pointer.
2. Object Sharing
Is there more than one other object that needs to access the object? If yes, then there is no way for these other objects to reference the shared object, other than holding its address.
Even if you have only one other object, but their lifetimes differ, the "lifetime" reason applies. If there is only one other object and their lifetimes match, than make it a field.
In attempting to answer another question, I was intrigued by a bout of curiousity, and wanted to find out if an idea was possible.
Is it possible to dynamically dereference either a void * pointer (we assume it points to a valid referenced dynamically allocated copy) or some other type during run time to return the correct type?
Is there some way to store a supplied type (as in, the class knows the void * points to an int), if so how?
Can said stored type (if possible) be used to dynamically dereference?
Can a type be passed on it's own as an argument to a function?
Generally the concept (no code available) is a doubly-linked list of void * pointers (or similar) that can dynamically allocated space, which also keep with them a copy of what type they hold for later dereference.
1) Dynamic references:
No. Instead of having your variables hold just pointers, have them hold a struct containing both the actual pointer and a tag defining what type the pointer is pointing to
struct Ref{
int tag;
void *ref;
};
and then, when "dereferencing", first check the tag to find out what you want to do.
2) Storing types in your variables, passing them to functions.
This doesn't really make sense, as types aren't values that can be stored around. Perhaps what you just want is to pass around a class / constructor function and that is certainly feasible.
In the end, C and C++ are bare-bones languages. While a variable assignment in a dynamic language looks a lot like a variable assignment in C (they are just a = after all) in reality the dynamic language is doing a lot of extra stuff behind the scenes (something it is allowed to do, since a new language is free to define its semantics)
Sorry, this is not really possible in C++ due to lack of type reflection and lack of dynamic binding. Dynamic dereferencing is especially impossible due to these.
You could try to emulate its behavior by storing types as enums or std::type_info* pointers, but these are far from practical. They require registration of types, and huge switch..case or if..else statements every time you want to do something with them. A common container class and several wrapper classes might help achieving them (I'm sure this is some design pattern, any idea of its name?)
You could also use inheritance to solve your problem if it fits.
Or perhaps you need to reconsider your current design. What exactly do you need this for?