This question already has answers here:
Why should I use a pointer rather than the object itself?
(23 answers)
Closed 3 years ago.
I am beginning development on a substantial personal project and wanted to ask a question regarding data members before doing so.
I am cognizant of the big differences between references and pointers. However, in my recent research, I have not found much (if any) clarification on the differences between data member values and pointers.
Consider the following two class definitions:
class A
{
private:
const std::string someString_;
};
class B
{
private:
const std::string *someString_;
};
What are the differences/nuances between the member data of classes A and B? Informed answers and relevant articles would be highly appreciated.
Similar question has been made here.
Basically, by using value you make a copy and by using pointer you hold a memory address.
A copy means that you already have an instance of the variable type and just copy its contents when you do an assignation.
A pointer means the variable can hold the memory address of an instance or null (none instance or invalid state). You can edit the value or the contents of a pointer. By modifying the value you're holding another memory address, by modifying the contents of a pointer you're actually editing the contents at that memory address.
In fact, the class A you showed, creates a std::string when it is instantiated. And the class B just has an address to a std::string.
You can play with the A's someString_ from the A's constructor. But, you should make a new std::string or pass a reference to a std::string in the B's constructor before attempt to modify the contents of B's someString_.
Related
This question already has answers here:
How do I pass smart pointers into functions?
(4 answers)
Should/Can smart pointers be passed by reference in functions
(2 answers)
Whether to pass shared pointer or raw pointer to a function
(2 answers)
Passing the address of dereferenced smart pointers to functions that expect raw pointers
(4 answers)
When should I use raw pointers over smart pointers?
(8 answers)
Closed 11 months ago.
I am trying to refactor some oldish code, and I want to use unique_ptrs for some objects where they are clearly suited. Up till now, shared_ptrs have been generally used.
Given that for most intents and purposes both smart pointers behave identically, in many cases I don't see why I should have to distinguish between the two. So to make a trivial example:
EDIT: I've had to make the object a little less trivial...
class NamedItem
{
string name;
string& GetName();
}
class SessionObject: public NamedItem
{}
class TrivialObject: public NamedItem
{}
class NameCacher:
{
vector<??????<NamedItem>> named_items;
void AddNamedItem(??????<NamedItem>& named_item)
{
named_items.push_back(named_item);
}
void PrintAllNamedItems()
{
// Print all names
}
}
unique_ptr<SessionObject> session(new SessionObject("the session"));
shared_ptr<TrivialObject> some_object(new TrivialObject("whatever"));
NameCacher names();
names.AddNamedItem(session); // The session pointer will not delete the session object, even if names stops referencing it.
names.AddNamedItem(some_object); // The some_object pointer is welcome to delete itself if names stops referencing it and nothing else is.
names.PrintAllNamedItems();
// If some_object goes out of scope, then its shared_ptr will delete it at this point.
Given that 80% of the day-to-day behaviour of the smart pointers is the same, isn't there a way to do this? The only thing I've found is to convert a unique_ptr to a shared_ptr - which is categorically not what I want to do. Ideally, I'd like the base class of the two smart pointers - but I can't find one.
Many thanks to all those who have responded to my question. I've been speaking with a knowledgeable colleague as well, and it's taken us about an hour to get a common understanding of the whole situation - so my apologies for not being able to convey this in my simplified example.
I thought I'd add this as an answer to explain to future readers why the premise of my question was ill-conceived. This attempts to summarise some of the comments on the original question.
I believe that I had misunderstood the utility of unique_ptrs, and had been using them incorrectly. What I had originally wanted was a pointer that behaved as a shared_ptr does, but did not need to manage its reference count - because I could guarantee that it would stay alive for the entire session. As such, the code which referenced it could treat it the same as a normal shared pointer - it is just didn't need to increment or decrement the reference count.
However, the purpose of a unique_ptr is that it's ownership can be transferred - and in my example above I am attempting to send it to another object while not transferring its ownership. As several commenters pointed out, this could be done much better by dereferencing it as a raw pointer or a reference as it is given to the recipient - but this would be a very different intention to when a shared_ptr is provided. As such, they shouldn't have a common interface as I had originally asked.
My thanks again for everyone who helped me understand my mistake.
This question already has answers here:
How to "return an object" in C++?
(8 answers)
Closed 8 years ago.
I am new to C++ and I'm stuck at the following problem:
Imagine you have a function that creates a new object and returns this object. What is the best approach to do that?
I have found 3 different solutions.
Solution 1 Using the copy constructor
MyClass getMyClass() {
MyClass obj;
//work with obj, set values...
return obj;
}
As far as I understod it, you create a new object, copy that object, destroy the first and return the copied object. So I created two object, but I only needed one. Is that right?
Solution 2 Creat the object on the heap and use pointer
MyClass* getMyClass() {
MyClass* obj = new MyClass();
//work with obj, set values...
return obj;
}
This seems to be the worst solution, you have to do memory management on your own.
Solution 3 Pass the object as a parameter
MyClass getMyClass(MyClass& obj) {
//work with obj, set values...
return obj;
}
You create a default object and set all values in the function.
I also thaught about using unique_ptr<MyCLass> but there is the same problem, that the unique_ptr is destroyed when the function scope is left.
Solution 1 does not use the copy constructor but return value optimization. It means that the object constructed in the function is actually not copied but passed to the caller of the function directly. Solution 1 is a very good option which I would recommend for non-polymorphic objects (i.e. no inheritance) which do not use too much space on the stack.
The preferred method for polymorphic objects would be Solution 2. But always think about who owns your objects, i.e. who is responsible for calling delete. A good alternative is using shared_ptr or unique_ptr.
Solution 3 does not really create the object, it only works with it once it is already created. It also does not make sense to return the object here.
Each of these has its own use cases, you can't say that one of them is better than the other or worst in all circumstances. It all boils down to your objects, how you create them, what are they supposed to interface to and where are they used.
And also there is the fourth, returning by using a shared pointer shared_ptr (in case you need shared ownership) or an auto pointer (unique_ptr or auto_ptr (sort of deprecated) ).
For example the one taking in a reference does not need to return the object too, that's an extra operation.
The one returning a pointer might not need to include a header file, a simple forward declaration might be enough (at least when you declare the function in the header file). But for this of course you will need to manually manage the memory (again: shared pointers might help here).
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I have a class really complicate, it has inside a vector of another class. I report one simpler, anyway it has inside the problem which I've been able to find.
// the inner class
class DuffyDuck{
int isblack; // 0 is white, 1 is black
int n_duck;
vector<DuffyDuck> * point_Duck;
public:
DuffyDuck(int isblack):isblack(isblack){
}
void set_point(vector<DuffyDuck> & Abitants){
point_Duck=&Abitants;
}
};
// the complessive class
class DuckCity{
vector<DuffyDuck> DuckAbitants;
public:
DuckCity(int numwhite,int numblack){
for(int i=0;i<(numblack+numwhite);++i){
DuckAbitants.push_back(DuffyDuck(i>=numblack));
DuckAbitants[i].set_point(DuckAbitants);
}
}
};
Now this works (i use point_Duck in several functions) but if I do something like that shown after once it's called in example "(*point_Duck)[2].n_duck;" in a function the project crashes.
That happens only if I do that:
DuckCity LittleTown(0,0);
LittleTown=DuckCity(3,5);
And after using some functions which call pointer.
If I do directly LittleTown(3,5) all is right.
I hope I explained well enough.
The DuffyDuck class is storing the address of a vector<> member of a DuckCity. Thus, when you copy the DuckCity to a different instance, that new instance will have a different vector<> instance. However, each DuffyDuck instance in that vector still has the address that was part of the old DuckCity instance.
So, your copy into littleTown yields dangling pointers.
I would recommend that you either rethink your design of DuffyDuck, or implement an assignment operator for DuckCity that performs a deep copy for each element of the vector<>. If you implement an assignment operator, remember to also follow the Rule of Three.
The cause of the problem is that each DuffyDuck has a pointer to a vector of DuffyDuck(s). When the class is destroyed the references become invalid --> crash.
DuckCity littleTown(1,2); // this creates a duck city
// with each duck pointing to the DuckAbitans vector.
littleTown=DuckCity(3,5); // this initializes another instance (call it INST)
// of DuckCity and
// then it assigns (via = operator) the value to littleTown
// by **copying** the DuffyDuck structures into a newly
// allocated vector. This makes the pointer of each DuffyDuck
// invalid after INST is destroyed (as it is a temporary object)
When you copy the address of Abitants, you are taking the address of the vector in the temporary object created by DuckCity(3,5). This temporary object is then copied into littleTown, and the original object destroyed. This means your original Abitats pointer is pointing at unused memory, which in turn leads to a crash.
It's hard to say exactly how you should fix this - probably by having a copy-constructor that "reconstructs" the Abitats pointer.
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'm an undergrad engineering student taking a senior/graduate-level CS course on simulation, and am in way over my head. I know that all of these can be found by searching resources online, but they are all such disjoint and shallow questions that it has proven difficult.
I'm just hoping for a few quick answer to a few questions.
I've seen "&" used a few different ways (address location, and to make permanent changes to variables passed as local variables into functions), but I have no idea what it does in this context. Event is a class.
bool operator>( const Event& e ) const {
return simulation_time > e.simulation_time;
}
After typing this out I realized that that operator is being applied to a pointer (address).. so it seems that "const Event& e" is equivalent to "const Event &e" (which I know is equivalent to "const Event & e")?
that is evil.
Next: what is the benefit of using const in such a straight forward situation?
an excerpt from a program:
my_heap->insert_event(event1);
[my_heap is an instance of a class which contains a vector based heap (and a function insert_event, which adds the event to the heap).]
What does the "->" mean?
All of the examples on pointers that I have seen go something like
int i = 2
int *p;
p = &i;
which is fine and dandy, but I've got this going on:
MinHeap *my_heap = new MinHeap();
and I don't understand what it's saying. I really can't even formulate an intelligent question. It just doesnt seem to me that it's pointing to an address at all...
-------------------------------
thanks in advance to anyone who takes the time to respond
The & operator
Has 2 primary uses: one is to take the address of a variable in memory, as you seem to be aware. So if I have int count = 0; the value of count is 0, but where is this variable in memory? &count will return this address, which can be useful in a variety of ways.
The other use is to declare/define a reference to a type. Note that in this context & is no longer an operator, and can not be given custom behavior in a user defined class. int & myRef represents a reference to an integer, which is very much like a pointer, but instead of having a variable to hold some address in memory, you are using one variable as a sort of pseudonym for another. int &myRef = count;, after this, count and myRef can be used 100% interchangeably. Note that this use only comes when defining or declaring a variable, never as the right hand side of an expression, or in other contexts. As you noted, whitespace is ignored for references, which is the same behavior as pointers.
const
It's always good behavior to use const when you can (in my opinion). It makes clear how variables will be used. Imagine if you have a function void foo(int & someIntRef) or void foo(int * someIntPtr). When I call foo, it is not guaranteed that the variable I pass in won't be changed. Maybe the integer I am passing in is something I am keeping track of very closely, and don't want anyone else to maybe or maybe not change it, so I would be forced to copy it to ensure the definition of foo, which I may not even have access to, doesn't alter the variable. In most situations, if I saw this function signature, I would assume the function would alter my variable. Also, there is a performance benefit if the compiler knows a function parameter is const, but as you are new to c++ it might be best to not worry about exactly how/why at this point.
-> operator
This is an operator (note, it may be overridden in custom classes, but it's very rare) that almost always access a data member or member function of a pointer to an object. If I have a struct:
struct Shape
{
int mSideCount;
};
...
Shape SomeShape;
Shape * ptrShape = &SomeShape;
I can access the mSideCount data member of SomeShape with SomeShape.mSideCount. But what about ptrShape? It's not a Shape, it's a pointer (specifically, Shape *). I have to dereference it first, with the * operator, like (*ptrShape).mSideCount. It's kinda ugly. To make life easier, -> exists to combine the dereference and member access: ptrShape->mSideCount.
new operator
new allocates memory for an object, and ensures it is constructed correctly (calls an appropriate constructor for the object, which is a member function that looks like Shape(){} in the case of the Shape example above). The big difference is where the memory comes from. When you create a variable like SomeShape above, it is created in a section of memory called the stack (hence, stack overflow). The stack usually has a relatively small maximum size, and any variables declared on the stack go away once the block (inside function brackets, loop brackets, whatever the block is) ends, so can't be use in other functions easily. new on the other hand by default creates the object using memory on the heap, which is more closely "all the memory on your system". There are books written about memory management and architecture alone, so this is an extremely brief introduction.
As many others have noted - these are fairly basic c++ concepts. You will be back here soon when you see other even less common language features. Get a good book, read through it, understand everything it says, do some of the examples, and then come here to fill in gaps in your knowledge that you still can't wrap your head around. I personally like c++ Dietle and Dietle, but anything will help you.
There is no difference between const Event& e and const Event &e.
Arrow operator -> is class member access operator used for pointers.
what is the benefit of using const in such a straight forward
situation?
This situation is called passing an argument by constant reference. Passing arguments just by value causes a copy to be made of that argument and that copy is used within the function. Passing by constant reference passes a reference to a function that is const - that means that the object is not copied. The const part ensures that you are not able to modify the reference argument (in the same way that you cannot change a regular constant variable)
MinHeap *my_heap = new MinHeap();
This is dynamic memory allocation. The new operator creates memory on the heap in which to place a new object of type MinHeap. After the space is allocated the new operator also calls the constructor that class and the returns a pointer to that object which you store as my_heap in your code. You then can modify the object that your pointer points to using the -> operator.
You should really consider buying an introductory text on C++ where these things are described in more detail
This is my first post in any forum so please bear with me.
I am writing a C++ program that utilizes a custom class 'Book' with member variables such as title, author and other variables that are stored in strings. Amongst these member variables is a vector for storing objects of type Review (which is another custom class). Now in my driver file (where the main() is located) needs to access that vector (the Reviews vector in each Book object) and make changes to it as well. I realized that I need to utilize a pointer of type vector
(eg.
vector pointerName
). So I added another member variable to the Books class which is a pointer. The problem I am facing is to point that pointer to the vector. Where can I make this assignment? I tried de-referencing it and pointing it to the vector in the default constructor for the object, but that causes my program to crash at run time without throwing an exception. The line I put in the constructor is
*pointer = vector_of_reviews;
I am new to this forum and still learning how to go about posting here so please bear with me if I have made a mistake in my post or if I was unclear or insufficient with my information. Please let me know if I need to post or say anything more to make my stance clear.
Thank You.
To assign a pointer to 'point to' an instance of an object use pointer = &vector_of_reviews.
The & operator gets the address of something, and it's this that you want to assign to the pointer.
*pointer = vector_of_reviews dereferences the pointer (obtains the actual object 'pointed to'). This would more than likely crash if the pointer is yet to be initialised. If the pointer was valid this would perform a value assignment, ie. invoke the vector class's assignment operator.