VS i konstruktor kopiujący

0

Witam

Chciałem was zapytać dlaczego po skompilowaniu tego kodu pod Visualem(testowane na 2008 i 2013 x64) "opcja2" odpala mi konstruktor kopiujący i destruktor ? Ten sam kod pod g++:

[dawid@lime ~]$ g++ -v
Using built-in specs.
Target: i386-undermydesk-freebsd
Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 4.2.1 20070831 patched [FreeBSD]

wydaje się działać normalnie - printscreen w załączniku

#include <string>
#include <iostream>

using namespace std;

class Seks
{
private:
	string zKim;
	char *zKimTab;
	int sizeTab;
	static int ileRazy;

public:
	Seks(double dziewczyny);
	Seks();
	Seks(const char *kto);
	Seks(string* kto);
	Seks(const string kto);
	Seks(const Seks &);
	~Seks();


};

int Seks::ileRazy = 0;
Seks::Seks(const char *ktoTab)
{
	cout << "6. Seks::Seks(const char *ktoTab)" << endl;
	size_t size = strlen(ktoTab);
	zKimTab = new char[size + 1];
	memset(zKimTab, 0, size + 1);
	memcpy(zKimTab, ktoTab, size);
	
	sizeTab = size + 1;

	ileRazy++;
}

Seks::Seks()
{
	
	cout << "1. Seks::Seks()" << endl;
	ileRazy++;
	zKimTab = NULL;
}

Seks::Seks(const string kto) : zKim(kto)
{
	cout << "7. Seks::Seks(const string kto)" << endl;
	ileRazy++;
	zKimTab = NULL;
}

Seks::Seks(string *kto) : zKim(*kto)
{
	cout << "2. Seks::Seks(string &kto)" << endl;
	ileRazy++;
	zKimTab = NULL;
}

Seks::Seks(const Seks &seksorg)
{
	cout << "3. Seks::Seks(const Seks &) - k. kopiujacy" << endl;
	if (seksorg.zKimTab != NULL)
	{
		sizeTab = seksorg.sizeTab;
		zKimTab = new char[sizeTab + 1];

		memset(zKimTab, 0, sizeTab + 1);
		memcpy(zKimTab, seksorg.zKimTab, sizeTab);
	}

}

Seks::~Seks()
{
	if (zKimTab != NULL)
	{
		delete[] zKimTab;
		sizeTab = 0;
		zKimTab = NULL;
	}

	ileRazy--;
	zKim = "";
	cout << "4. Seks::~Seks()" << endl;
}

Seks::Seks(double dziewczyny)
{
	
	cout << "5. Seks::Seks(double dziewczyny)" << endl;
	ileRazy++;
	zKimTab = NULL;
}

int main(void)
{
	int breakpoint = 0;

	{
	cout << "-- Opcja 1: --" << endl;
	char *napis = "aaaa";
	Seks sx1 = Seks(napis);
	breakpoint = 0; // a) ustaw tu breakpointa. co się pojawi i dlaczego tak?
	
	cout << "-- Opcja 2: --" << endl;
	const string fl = "opcja2";
	Seks sx2 = Seks(fl); 
	breakpoint = 0; 
	//b) ustaw tu breakpointa. co się pojawi i dlaczego tak ?
	// Wywola sie konstruktor kopiujacy ponieważ ?

	cout << "-- Opcja 3: --" << endl;
	string *ptr = new string("opcja3");
	Seks sx3 = Seks(ptr); 
	breakpoint = 0; // b) ustaw tu breakpointa. co się pojawi i dlaczego tak ? 
	delete ptr; // mozemy usunac bo juz mamy kopie stringu  "opcja3" w sx3, dzieki: Seks::Seks(string *kto) : zKim(*kto)
	
	cout << "-- Opcja 4 --" << endl;
	Seks sx4;
	breakpoint = 0; // c) ustaw tu breakpointa. co się pojawi i dlaczego tak ? // jasne
	
	cout << "-- Opcja 5: --" << endl;
	Seks sx5 = Seks(2);
	breakpoint = 0; // d) ustaw tu breakpointa. co się pojawi i dlaczego tak ? // jasne

	cout << "-- Opcja 6: --" << endl;
	cout << "Tworze obiekt *: " << endl;
	Seks *sx6 = new Seks("XXX");
	breakpoint = 0; // f1) ustaw breakpointa. co sie pojawi i dlaczego ? // jasne
	cout << "Usuwam obiekt *: " << endl;
	delete sx6;
	breakpoint = 0; // f2) ustaw breakpointa. co sie pojawi i dlaczego ? // jasne
}
	
	return 0;
}

Dzięki
Dawid

0
Seks::~Seks()
{
    if (zKimTab != NULL)
    {
        delete[] zKimTab;

Na tym się kod wywala, bo zKimTab było niezainicjalizowane (nie jest więc NULLem) i zawiera śmieci.

Jedyna możliwość że zKimTab pozostaje niezaincjalizowane, to niespełniony warunek w konstruktorze kopiującym:

    if (seksorg.zKimTab != NULL)

To znaczy że dochodzi do kopii pustego obiektu, a konstruktor nie jest na to odporny.
Najlepiej wyrzuć ten warunek po prostu, bo tylko szkodzi.

Konstruktor kopiujący wywoływany jest tutaj:

   Seks sx2 = Seks(fl);

To jest implementation dependent, czy zostanie wywołany k.kopiujący w tym przypadku, czy nie.
W przypadku Visuala, zniknie ci kopiowanie gdy skompilujesz kod z optymalizacją /Ox.

Najlepiej napisz po prostu:

	Seks sx2(fl);

I masz gwarantowany brak kopii.

0

Tą tablice znaków zrobiłem na szybko i "byle jak" także nie zadbałem o resztę. Chodziło mi bardziej sprawdzenie czemu tak a nie inaczej w kwestii cctor'a.

Konstruktor kopiujący wywoływany jest tutaj:
Seks sx2 = Seks(fl);

Przeanalizowałem to sobie w paint'cie ;D (printscreen w załączniku) zaraz po utworzeniu tego tematu... i drugie pytanie jakie miałem zadać to czemu akurat dla "opcja2" kompilator VS wykonuje cctor`a a obiekty: sx1, sx3, sx5 tworzy normalnie. Rozumiem dlatego, że je dobrze zoptymalizował ?

O pojęciu "implementation dependent" poczytam.

0

i zapomniałem podziękować.

Dzięki Azarien :-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1