Προς το περιεχόμενο

C++ και επιστροφή αντικειμένου από συνάρτηση


sir ImPeCaBlE

Προτεινόμενες αναρτήσεις

1 ώρα πριν, sir ImPeCaBlE είπε

Αυτό σκεφτόμουν και εγώ όταν το έγραφα γιατί ερχόμουν από java. Κολλάω στο εξής:

η μνήμη για αυτό το αντικείμενο δεσμεύτηκε μέσα στη συνάρτηση. Άρα όταν βγω από τη συνάρτηση, δε θα αποδεσμευτεί?

Θα καταλάβαινα να δούλευε αν είχα δεσμεύσει μνήμη ρητά με new/malloc (και μετά έπρεπε να κάνω delete/free) ή να έκανε copy τις τιμές αλλά δε χρησιμοποιεί τον copy constructor.

Έβαλα και ένα -O0 στον g++ για να δω μήπως κάνει καμία περίεργη βελτιστοποίηση αλλά δεν άλλαξε κάτι.

ArrayTest a;
ArrayTest b = a + 'kati'; // σε αυτό το namespace γίνεται η δεύσμευση τη μνήμης το a γίνεται copy παίρνει και νέο string επιστρέφεται και ανατίθεται στο b

αυτό είναι το ίδιο όπως

int func ()
{
	int a = 10; 
	return a;
}

int b = func();

πού είναι το b μέσα στη συνάρτηση; Όχι βέβαια, στο namespace που δημιουργείται

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)
17 ώρες πριν, sir ImPeCaBlE είπε

Όσο το ψάχνω τόσο μπερδεύομαι.

Thanx για την απάντηση. Ο copy constructor μου καλείται μια φορά για το 


ArrayTest n = ArrayTest(*this);

Δε τον βλέπω να ξανακαλείται από κάτι άλλο.


int main(){
	ArrayTest t = ArrayTest(6);
	t.add("first");
	t.add("second");
	t.add("third");
	ArrayTest k = (t+"fourth");
	cout<<&k<<"\n";
	cout<<k.print();
}

Αυτό μου έβγαλε ότι η διεύθυνση του k είναι η ίδια με τη διεύθυνση του "n" μέσα στην "operator +". Πωτς γκενεν αυτό?

Εχουν ιδια διευθυνση γι' αυτο κανει copy ellision. Περασε στον gcc το -fno-elide-constructors και θα δεις πως μετα ειναι διαφορετικες. Δεν ξερω γιατι αλλα κανει ellision ουτως η αλλως, χωρις να το ορισεις με καποιο -O flag. Επισης εχω gcc version 10.1.0.

Επεξ/σία από xristos97
  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Άρα ο κώδικας κάνει return by value. Λόγο βελτιστοποιήσεων του compiler δε γίνεται το copy στο αποτέλεσμα και delete της εσωτερικής μεταβλητής αλλά απλά αναθέτει στο αποτέλεσμα κατευθείαν την διεύθυνση της εσωτερικής μεταβλητής. Σωστά κατάλαβα?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

1 ώρα πριν, sir ImPeCaBlE είπε

Άρα ο κώδικας κάνει return by value. Λόγο βελτιστοποιήσεων του compiler δε γίνεται το copy στο αποτέλεσμα και delete της εσωτερικής μεταβλητής αλλά απλά αναθέτει στο αποτέλεσμα κατευθείαν την διεύθυνση της εσωτερικής μεταβλητής. Σωστά κατάλαβα?

Ναι κάπως έτσι είναι. Ψάξε για copy ellision αν θες να μάθεις περισσότερα.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

6 ώρες πριν, sir ImPeCaBlE είπε

Άρα ο κώδικας κάνει return by value. Λόγο βελτιστοποιήσεων του compiler δε γίνεται το copy στο αποτέλεσμα και delete της εσωτερικής μεταβλητής αλλά απλά αναθέτει στο αποτέλεσμα κατευθείαν την διεύθυνση της εσωτερικής μεταβλητής. Σωστά κατάλαβα?

Όχι. Δεν κατάλαβες σωστά. Στο return δεν υπάρχει by value, by reference. To τι επιστρέφει κάθε συνάρτηση καθορίζεται σαφώς στο definition και είναι datatype    ή pointer. Πιάσε το tutorial από την αρχή

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • 4 εβδομάδες αργότερα...
Στις 11/7/2020 στις 1:58 ΜΜ, sir ImPeCaBlE είπε

Άρα ο κώδικας κάνει return by value. Λόγο βελτιστοποιήσεων του compiler δε γίνεται το copy στο αποτέλεσμα και delete της εσωτερικής μεταβλητής αλλά απλά αναθέτει στο αποτέλεσμα κατευθείαν την διεύθυνση της εσωτερικής μεταβλητής. Σωστά κατάλαβα?

Σωστά.

Ο compiler κανονικά πρέπει να κάνει copy το αντικείμενο που επιστρέφεις και να ελευθερώσει τη μνήμη από την σύνάρτηση (τον overloaded operator), όπως γίνεται σε κάθε τοπική μεταβλητή σε μια μέθοδο. Επειδη έτσι όμως γίνονται παραπάνω κόπιες του ίδιου αντικειμένου, ο compiler μπορεί να κάνει ένα optimization που λέγεται Return Value Optimization έτσι ώστε να αποφύγει τις έξτρα κόπιες.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...