Question about List of Objects in dart Language (Flutter) - list

Question About List of Objects in dart (Flutter)
Hello
class Cartoon {
.
.
}
List<Cartoon> L1 = [];
….
...
List<Cartoon> L2 = [];
I define below a new list L2 containing objects from List L1 meeting some condition
List<Cartoon> L2 = [];
L2.clear();
for (Cartoon _thisObjet in L1) {
if (_thisObjet.xxx == yyyy) { //
L2.add(_thisObjet);
}
}
I check with the debugger that anytime I modify a member Value in an Object L2 , the member is is also modified in member of. original Object in List L1.
This is not expected result
In my mind I was thinking these 2 Lists should be independent ,So if someone has an explanation, I would be grateful

All variables in Dart is references to objects. The same for lists where lists only contains references to objects.
So your List<Cartoon> contains references to Cartoon objects. That means that when you look though L1 you are going though references to Cartoon objects and when you insert one of these references to the L2 list, you now have two lists containing a reference to the same object.
That also means that when you are making changes inside this object, the change can be observed when iterating though both of the lists since there are only one object.
So if you want to prevent a change to a Cartoon object to be observed in your other list, you need to make a copy of your Cartoon object and make the change on the copy. The best you can do here is to make a method on Cartoon which returns a copy of the object or make a constructor which takes a Cartoon object to create another Cartoon object.
(An important note related to this topic is immutable objects like int, String and so on (e.g. your own type of objects which only contains final fields). These type of objects cannot change their inner state but you are forced to create a new object every time you want to impose a change. By making immutable objects, you can prevent this kind of issues since any change to the object forces you to get a new object. But note, like everything, immutable is not a silver bullet to solve all problems.)

Related

Why is concatenating two linked lists by assigning pointers wrong?

So our lecturer just showed us how to concatenate two linked list but then went on and showed us and example that would be wrong if implemented,I don't seem to quite understand why it won't work as good,since it wasn't explained.What would be the problem if I concatenate two linked lists this way:
template <typename T>
void LList<T>::concat(LList<T> const & list) {
end->next = list.start;
end = list.end;
}
The approach used in the question is wrong because it incorrectly shares Ownership of the transferred nodes.
list owns its nodes. It maintains and ultimately releases them. By giving pointers to nodes owned by list to the receiving linked list, you will now have two linked lists referring to and trying to own the same set of nodes. If you later modify list, you will modify the receiver and potentially leave it in an inconsistent state (end may no longer be correct, for example). If you later destroy list, the receiver is left pointing to invalid memory after list destroys its nodes. Likewise list is left in a precarious state by modifying or destroying the receiver.
This is somewhat related to The Rule of Three, and it's the copy constructor required by Rule of Three that I'd take advantage of to get out of this mess. I'd pass list in by value rather than as a reference so that it is correctly duplicated and then move its list of nodes, copies of the nodes owned by the source list, into the receiving linked list. You can then clean up list so that it is safe to destroy and leave it to die when it goes out of scope. This approach may be a little slow, but it's very nearly foolproof. See the Copy and Swap Idiom for a nearly identical trick being applied to the assignment operator.

How to model changing state in functional programming

I am new to FP and new to Scala and I have a question on how to solve a problem efficiently in a functional way.
Let's say I have:
case class Store(storedObjects: List[StoreObject])
and
case class StoreObject(name: String)
and I want to store all the StoreObjects in the Store.
How can I add new StoreObjects to the List the Store case class owns when it's immutable?
To take a second example: Suppose I have a case class Person as shown here,
case class Person(name: String)
and an object called object PersonController
which owns an immutable list of Persons and every time I create a new Person I want to add it to the list in PersonController.
Is there a way how to do this in fp or a pattern?
Or is switching to mutability the only efficient way to do stuff like this (which would be painful because of multithreading).
Thanks for your help
Exagon
I think the main idea you're missing right now is the possibility to not mutate at all but actually create a new object with the result of your addition/removal operation.
For adding... something along these lines for example:
def add(sObject: StoreObject, store: Store) = store.copy(storedObjects = store.storedObjects :+ sObject)
This will return a new Store holding the list.
Hope this makes sense and answer your doubts.
how can i add new StoreObjects to the List the Store Class owns
Define a regular class with field
var list = List()
or
val list = mutable.List()
You can change this field in both cases: in first case by reassigning the var and in second by mutating the underlying mutable.List.
I would prefer the first way - var with immutable list, because you can safely share it among threads. But you have to ensure that update operations on list are correctly synchronized.

How would a QList containing pointers behave when passed by value

Suppose you have QList containing pointers QList<SomeThingCool*> and you pass it to a method with a signature void doCoolStuff(QList<SomeThingCool*> list) what would the space and time implications be of such a call?
My guess is that there will be some overhead because a copy will be created of the QList object, we however do not need to do a deep copy since we are dealing with pointers.
One difference in behaviour would be that if doCoolStuff makes modifications to the list, the original list will remain untouched.
What you are writing is correct for generic C++, however QList, among some other Qt classes, is a bit special when it comes to this. It is implicitly shared a class, aka. copy-on-write (COW). What does that mean, yeah?
The only addition to your explanation is that if you do not intend to modify the list inside the body of the method or function, your list be implicit shared, which means a shared data pointer will be only the extra space constraint.
If you intend to modify the list inside the function or method body, then there will be a deep copy made for the list. Naturally, your pointers will still remain shallowly copied because they are pointers.
As for the time dimension, by implicitly using this technique for this class, you spare the time spent on copying the list if you do not do any modification.

Making a list of variables without copying them

The Main question:
How do you create a pointer to a variable that can be stored and then used to access this variable at a later time Without a copy being created
The below is here just to answer any questions that people might have as to why I want to do this
Prologue:
I am making a game with DirectX and I want to create a "list" of Entities(A special class) in a another class. I want to do this so I can keep track of all the objects in the game that are rendered by a specific method(One list for triangles, another for lines, ect). To do this I originally just had a class and it had a std::vector<Entity>, the class then had an add(Entity entity) function which would add the specified entity to the vector. This worked out very well until I started trying to make changes to these entities in the vector.
The problem:
First I would create an entity in the main world loop, Entity testEntity = Entity(position); then I would add it to the entity list, entityList.add(testEntity);. When this command is called it is actually just making a copy of the entity as it is at the time that the add command was called. This means that there are suddenly 2 entities that represent 1, The entity in the main world that is being affected by all the game logic, and the entity in the entityList that does not update, but renders. These two are not in sync.
The desired effect:
The entityList's std::vector is actually just filled with some sort of pointer to the entities in the world loop. Then when an entity is updated in the world loop the entityList has the same data for that entity.
It's not entirely clear to me where you're having trouble, so this may not answer the question:
It seems like you want to just store a vector of pointers to Entity objects. I.e. std::vector<Entity*>.
If you know that testEntity will be in scope for the lifetime of the vector, you could just add a pointer to it to your vector. I.e. entityList.add(&testEntity).
If that assumption isn't true, you probably want to allocate your Entity objects on the heap (e.g. Entity* testEntityPtr = new Entity(position);. If you're using C++11 (or maybe even if you're not), you probably want to use shared_ptr and make_shared in this situation.
You could possibly use the c++ 11 Move Semantics to preserve your data. If Entity have pointer members that point to some allocated data that you do not want to copy you could implement Move semantics that would essentially transfer ownership the the copy that you are placing in the vector.
For example:
Entity(Entity&& entity)//move constructor
{
this->data = std::move(entity.data);
//and so on.
}
You will also need a "Move assignment operator" Entity& operator=(Entity&& entity);
You will need to look up "Move Semantics" and "rvalue references" for more info.
I hope this helps.

Copy list objects value not reference

I'm try to create a new list object. I set the new object to an old existing object.
List<string> names = new List<string>();
names = olderList;
The problem I have is that the names list points to the olderList as a result when olderList changes, names changes too. I tried copying the values with a foreach but it's still doing the same thing, refering to the olderList.
When you make an assignment in Java, you copy the reference, not the content. Therefore, names will point to the same memory address that olderList does.
When you copy all the values, you do the same thing - you are assigning to the names list another reference to each String stored in the olderList.
An idea that might solve your problem is to use the foreach but instead of adding each element, creating a new String that is a copy of the old one. It would be something like this:
names=new List<String>();
foreach (String s: olderList) {
names.add(new String(s));
}
Check the constructor I used and its meaning at Oracle's reference site.
You must create a new list and clone every element.
If you call
olderList.clone()
it will give you a shallow copy (i.e. a new list with references to the objects of the first list). You must do something like this:
for(String name : olderList){
newList.add(name.clone());
}
reference: java api Cloneable, Object.clone()