Destructor of a class is been called twice

The program below compiles and runs as it should. However the destructor is being called twice, and I can't figure out why? Can you take a look and help me?
The output is:
"Your profile is created!
Arya Stark
Customer Number: 7 - Cost of the fare:180.00 - Customer Points: 4
Good Effort

Name: Arya Stark- Fee: 12- Rating: 0.10
Good Effort"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  #include "stdafx.h"
#include <iostream>
#include <cstring>
#include <locale>
#include <string>
#include <string.h>
#include <iomanip>

class UberDriver {
public:
	std::string name;
	int fee_per_km;
	double uber_wallet;
	double uber_points;
	int customer_counter;
	UberDriver(std::string n, int fpk, double uw, double up, int cc) {
		name = n;
		fee_per_km = fpk;
		uber_wallet = uw;
		uber_points = up;
		customer_counter = cc;
		std::cout << "Your profile is created" << std::endl;
	};
	std::string get_name() { return name; }
	int get_fee_per_km() { return fee_per_km; }
	double get_uber_wallet() { return uber_wallet; }
	double get_uber_points() { return uber_points; }
	int get_customer_counter() { return customer_counter; }
	void set_name(std::string n) {
		name = n;
	}
	void set_fee_per_km(int fpk) {
		fee_per_km = fpk;
	}
	void set_uber_wallet(double uw) {
		uber_wallet = uw;
	}
	void set_uber_points(double up) {
		uber_points = up;
	}
	void set_customer_counter(int cc) {
		customer_counter = cc;
	}
	void print_uber_profile() {
		double avg;
		avg = (uber_points / customer_counter);
		std::cout << "Name: " << name << "- Fee: " << fee_per_km << "- Rating: ";
		std::cout << std::fixed << std::setprecision(2) << avg << std::endl;
	}
	~UberDriver() {
		if (uber_wallet >= 100.00) {
			std::cout << "Great Job" << std::endl;
		}
		else if (uber_wallet < 100.00&&uber_wallet >= 50.00) {
			std::cout << "Good Effort" << std::endl;
		}
		else {
			std::cout << "Try Harder" << std::endl;
		}
	}
};

void uber_call(UberDriver driver, double km) {
	double l;
	int customer_points = 0;
	if (driver.uber_points > 6 && driver.uber_points < 9) {
		customer_points = 8;
		l = km * (driver.fee_per_km);
	}
	else if (driver.uber_points <= 6) {
		customer_points = 4;
		driver.customer_counter = driver.fee_per_km / 2;
		l = km * (driver.fee_per_km);
	}
	else if (driver.uber_points >= 9) {
		l = km * (driver.fee_per_km) + 5.0;
		customer_points = 10;
	}
	std::cout << "Customer Number: " << driver.customer_counter + 1 << " Cost of the fare:";
	std::cout << std::fixed << std::setprecision(2) << l << std::endl;
	std::cout << " Customer Points: " << customer_points;
};

int main() {
	UberDriver driver("Arya Stark", 12, 101.5, 4.7, 23);
	std::cout << driver.name;
	driver.customer_counter = 21;
	driver.uber_points = 9.6;
	uber_call(driver, 15.0);
	return 0;
}
The uber_call function takes its arguments by value (which is the default in C++ for all types).
This means that the function will receive a copy of the UberDriver object that you pass to it.

If you want to avoid creating a copy you need to change function to take the argument by reference, like so:

 
void uber_call(const UberDriver& driver, double km) {

const isn't strictly necessary but it's usually a good idea when the function is not supposed to modify the object.
On line 63 the parameter driver is a copy of the provided object, hence it is constructed and at the end of the function destructed. If you don't want this copy you may pass a const reference:

void uber_call(const UberDriver &driver, double km) {
The first one is the destructor of 'driver' on line 82. This UberDriver was created on line 63 with copy construction due to the function call on line 89.

The second one is the destructor of 'driver' on line 91. This UberDriver was created on line 85.


You do pass argument to function by value. That is a copy operation. (Could be a move in current C++11, but there would still be distinct objects.)

The alternative is argument by reference.
Oh, I see. Thank you for your help. I will try to keep that in mind next time.
Topic archived. No new replies allowed.