Inicjalizacja wskaźnika na T referencją do T

0
#include <iostream>
#include <cstring>
#include <string>
using namespace std;


class Person {
	char* name;

public:

explicit Person(const char* n)
	{
		name = new char[strlen(name)+1 ];
		strcpy(name, n);
	}

Person(const Person& os)
	{
		name = new char[strlen(os.name)+1 ];
		strcpy(name, os.name);
	}

Person& operator=(const Person& os)
	{
		if (&os != this)
		{
			delete[] name;
			name = new char[strlen(os.name)+1 ];
			strcpy(name, os.name);
		}
		return *this;
	}

friend class Couple;

friend std::ostream& operator<<(std::ostream& str,const Person& os)
	{
		str << os.name;
		return str;
	}

~Person()
	{
		cout << "Delete " << name;
		delete[] name;
	}
};



class Couple {
	Person *wife, *husband;
public:
	Couple(const Person& she, const Person& he):wife(she),husband(he){}
	Couple(const Couple& other):wife(p.wife),husband(p.husband){}
	Couple& operator=(const Couple& other)
	{
		husband = p.husband;
		wife = p.wife;
		return*this;
	}


	friend std::ostream& operator<<(std::ostream& str,const Couple& p)
	{
		str << p.husband << " " << p.wife;
		return str;
	}

~Couple();

};

int main(void) {

	Person *pjohn = new Person("John"),
		*pjane = new Person("Jane");
	Person mary("Mary"), mark("Mark");
	Couple *pcouple1 = new Couple(mary, *pjohn);
	Couple couple2(*pjane, mark);
	delete pjohn;
	delete pjane;
	cout << *pcouple1 << endl;
	cout << couple2 << endl;
	couple2 = *pcouple1;
	delete pcouple1;
	cout << couple2 << endl;
}

Wywala mi błędy :

||=== Build: Debug in Zadanie10 (compiler: GNU GCC Compiler) ===|
||In constructor 'Couple::Couple(const Person&, const Person&)':|
|55|error: cannot convert 'const Person' to 'Person*' in initialization|
|55|error: cannot convert 'const Person' to 'Person*' in initialization|
|56|error: 'p' was not declared in this scope|
||In member function 'Couple& Couple::operator=(const Couple&)':|
|59|error: 'p' was not declared in this scope|
||=== Build failed: 4 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

Jak by mi ktoś podpowiedział jak to naprawić to by super było.

2

Mylisz wskaźnik z referencją. Nie możesz wskaźnika na T zainicjalizować za pomocą obiektu T. Najmniejsza zmianą "naprawiającą" kod będzie inicjalizacja

Couple(const Person& she, const Person& he):wife(new Person{she}),husband(new Person{he}){}

Tylko po co te wszystkie new? Polecam lekturę: https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete/

Gdybyś użył std::string, referencji tam gdzie trzeba i wskaźników jako obserwerów to byś miał 3x mniej kodu, bez błędów i czytelniejszego.

0

Zmieniłem, ale teraz mi wywala

||=== Build: Debug in Zadanie10 (compiler: GNU GCC Compiler) ===|
||In constructor 'Couple::Couple(const Person&, const Person&)':|
|55|warning: extended initializer lists only available with -std=c++11 or -std=gnu++11|
|55|warning: extended initializer lists only available with -std=c++11 or -std=gnu++11|
|56|error: 'p' was not declared in this scope|
||In member function 'Couple& Couple::operator=(const Couple&)':|
|59|error: 'p' was not declared in this scope|
||=== Build failed: 2 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|
1

No to kompiluj z jakimś nowym standardem C++, mamy 2018 rok, nie ma co się kurczowo trzymać C++98 ;​)

https://stackoverflow.com/questions/18174988/how-can-i-add-c11-support-to-codeblocks-compiler

Wybierz C++17 > C++14 > C++11, któryś musi być dostępny.

0
kq napisał(a):

No to kompiluj z jakimś nowym standardem C++, mamy 2018 rok, nie ma co się kurczowo trzymać C++98 ;​)

Nie wiedziałem że samemu standard muszę wybrać, założyłem błędnie że code block sam mi wybierze najnowszy standard. Zmieniłem mu na c++17 ;]

To zostało mi jeszcze zainicjować p.husband jakoś.
|59|error: 'p' was not declared in this scope

2

W tym konstruktorze nie ma obiektu o nazwie p.

Couple& operator=(const Couple& other)
    {
        husband = p.husband;
        wife = p.wife;
        return*this;
    } 
Couple& operator=(const Couple& other)
    {
        husband = other.husband;
        wife = other.wife;
        return*this;
    } 
0

Masakra myślałem że łatwiej pójdzie a tu z 1 błędu na drugi ;[

#include <iostream>
#include <cstring>
#include <string>
using namespace std;


class Person {
	char* name;

public:

explicit Person(const char* n)
	{
		name = new char[strlen(name)+1 ];
		strcpy(name, n);
	}

Person(const Person& os)
	{
		name = new char[strlen(os.name)+1 ];
		strcpy(name, os.name);
	}

Person& operator=(const Person& os)
	{
		if (&os != this)
		{
			delete[] name;
			name = new char[strlen(os.name)+1 ];
			strcpy(name, os.name);
		}
		return *this;
	}

friend class Couple;

friend std::ostream& operator<<(std::ostream& str,const Person& os)
	{
		str << os.name;
		return str;
	}

~Person()
	{
		cout << "Delete " << name;
		delete[] name;
	}
};



class Couple {
	Person *wife, *husband;
public:
	Couple(const Person& she, const Person& he):wife(new Person{she}),husband(new Person{he}){}
	Couple(const Couple& other):wife(other.wife),husband(other.husband){}
	Couple& operator=(const Couple& other)
	{
		husband = other.husband;
		wife = other.wife;
		return*this;
	}


	friend std::ostream& operator<<(std::ostream& str,const Couple& other)
	{
		str << other.husband << " " << other.wife;
		return str;
	}

~Couple();

};
// implementation
int main(void) {

Person *pjohn = new Person("John"),
        *pjane = new Person("Jane");
    Person mary("Mary"), mark("Mark");
    Couple *pcouple1 = new Couple(mary, *pjohn);
    Couple couple2(*pjane, mark);
    delete pjohn;
    delete pjane;
    cout << *pcouple1 << endl;
    cout << *couple2 << endl;
    couple2 = *pcouple1;
    delete *pcouple1;
    cout << couple2 << endl;
}

||=== Build: Debug in Zadanie10 (compiler: GNU GCC Compiler) ===|
G:\Projekty c++\Zadanie10\main.cpp||In function 'int main()':|
G:\Projekty c++\Zadanie10\main.cpp|85|error: no match for 'operator*' (operand type is 'Couple')|
G:\Projekty c++\Zadanie10\main.cpp|87|error: type 'class Couple' argument given to 'delete', expected pointer|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

pozmieniałem wszystkie p.whife itd na other.wife itd teraz widzi ale czemu cout i delete akurat nie działają ( długa droga przede mną jeszcze zanim to ogarnę )wszystko ;[

1

delete pcouple1;

0
#include <iostream>
#include <cstring>
#include <string>
using namespace std;


class Person {
	char* name;

public:

explicit Person(const char* n)
	{
		name = new char[strlen(name)+1 ];
		strcpy(name, n);
	}

Person(const Person& os)
	{
		name = new char[strlen(os.name)+1 ];
		strcpy(name, os.name);
	}

Person& operator=(const Person& os)
	{
		if (&os != this)
		{
			delete[] name;
			name = new char[strlen(os.name)+1 ];
			strcpy(name, os.name);
		}
		return *this;
	}

friend class Couple;

friend std::ostream& operator<<(std::ostream& str,const Person& os)
	{
		str << os.name;
		return str;
	}

~Person()
	{
		cout << "Delete " << name;
		delete[] name;
	}
};



class Couple {
	Person *wife, *husband;
public:
	Couple(const Person& she, const Person& he):wife(new Person{she}),husband(new Person{he}){}
	Couple(const Couple& other):wife(other.wife),husband(other.husband){}
	Couple& operator=(const Couple& other)
	{
		husband = other.husband;
		wife = other.wife;
		return*this;
	}


	friend std::ostream& operator<<(std::ostream& str,const Couple& other)
	{
		str << other.husband << " " << other.wife;
		return str;
	}

~Couple(){                                                     // nic nie zmienia czy jest czy nie ma wysypuje program
cout << "Delete " << husband;
		delete[] husband;
		cout << "Delete " << wife;
		delete[] wife;
	}

};
 
int main(void) {

Person *pjohn = new Person("John"),
        *pjane = new Person("Jane");
    Person mary("Mary"), mark("Mark");
    Couple *pcouple1 = new Couple(mary, *pjohn);
    Couple *couple2 = new Couple(*pjane, mark);
    delete pjohn;
    delete pjane;
    cout << *pcouple1 << endl;
    cout << *couple2 << endl;
    *couple2 = *pcouple1;
    delete pcouple1;
    cout << couple2 << endl;
}

Troszka pozmieniałem main i dodałem dekonstruktor teraz mi wywala:

Process terminated with status -1073741819 (0 minute(s), 46 second(s))

Czyli pewnie pamięć wycieka ;[

1

Tutaj name jest jeszcze pustym wskaźnikiem więc nie można wykonać na nim operacji strlen().

name = new char[strlen(name) + 1]; 

Tak już powinno być dobrze. Raczej o to powinno chodzić, bo n jest argumentem ctora, i to jego zawartość próbujesz kopiować
do name.

name = new char[strlen(n) + 1];

W jakim celu jest ten

friend class Couple; 
0

friend class Couple; było w zadaniu założyłem że jest tam potrzebne by klasa Couple mogła korzyztać z klasy person.
Aktualnie drukuje mi
Delete JohnDelete Jane0x2f61248 0x2f61118
0x2f61278 0x2f61228
Delete 0x2f61248
Process returned -1073741819 (0xC0000005) execution time : 8.204 s
Press any key to continue.
powinno wyświetlić
DEL John
DEL Jane
Couple: he John, she Mary
Couple: he Mark, she Jane
DEL Jane
DEL Mark
DEL Mary
DEL John
Couple: he John, she Mary
DEL Mary
DEL John
DEL Mark
DEL Mary
Endl nie powstawiałem ale to jak wyświetla jest najmniej ważne wyświetla mi z tego co rozumiem adresy do komurek pamięci a nie do ich zawartości i dlatego mam 0x2f61248.

0
#include <iostream>
#include <cstring>
#include <string>
using namespace std;


class Person {
	char* name;

public:

explicit Person(const char* n)
	{
		name = new char[strlen(n)+1 ];
		strcpy(name, n);
	}

Person(const Person& os)
	{
		name = new char[strlen(os.name)+1 ];
		strcpy(name, os.name);
	}

Person& operator=(const Person& os)
	{
		if (&os != this)
		{
			delete[] name;
			name = new char[strlen(os.name)+1 ];
			strcpy(name, os.name);
		}
		return *this;
	}

friend class Couple;

friend std::ostream& operator<<(std::ostream& str,const Person& os)
	{
		str << os.name ;
		return str;
	}

~Person()
	{
		cout << "Delete " << name << endl;
		//delete[] name;
	}
};



class Couple {
	Person *wife, *husband;
public:
	Couple(const Person& she, const Person& he):wife(new Person{she}),husband(new Person{he}){}
	Couple(const Couple& other):wife(other.wife),husband(other.husband){}
	Couple& operator=(const Couple& other)
	{
		husband = other.husband;
		wife = other.wife;
		return*this;
	}


	friend std::ostream& operator<<(std::ostream& str,const Couple& other)
	{
		str << other.husband << " " << other.wife;
		return str;
	}

~Couple(){
cout << "Delete " << husband << endl;
		//delete[] husband;
		cout << "Delete " << wife << endl;
		//delete[] wife;
	}

};

int main(void) {

Person *pjohn = new Person("John"),
        *pjane = new Person("Jane");
    Person mary("Mary"), mark("Mark");
    Couple *pcouple1 = new Couple(mary, *pjohn);
    Couple *couple2 = new Couple(*pjane, mark);
    delete pjohn;
    delete pjane;
    cout << *pcouple1 << endl;
    cout << *couple2 << endl;
    *couple2 = *pcouple1;
    delete pcouple1;
    cout << couple2 << endl;
}

w dekonstruktorze miałem delete niepotrzebnie i mi kasował dane z pamięci przez co zwracało adres póstej komurki i sie sypał program ;]
teraz jest program stabilny ale dalej nie mogę dojść jak się dostać do pamięci zamiast adresu próbowałem z & ale to zmienia tyle ze zamiast 2 adresów po delete jana mam 1 ;[
Drukuje :

Delete John
Delete Jane
0x1f1158 0x1f10b8
0x1f1268 0x1f1248
Delete 0x1f1158
Delete 0x1f10b8
0x1f11e8
Delete Mark
Delete Mary

Process returned 0 (0x0) execution time : 0.012 s //jężeli dobrze rozumiem to program działa prawidłowo jak wywala zero ;]
Press any key to continue.

2

Wszędzie tam gdzie są wypisywane adresy należy użyć operatora dereferencji, aby wyłuskać wartości, zamiast wypisywać adresy.
Tutaj:

str << *other.husband << " " << *other.wife; 

i jeszcze w kilku miejscach.

Po zrobieniu zadania należy szybko zapomnieć o char* oraz new i delete i używać jak wspomniał @kq std::string oraz smart pointery.

0

Działa dziki wielkie za pomoc i cierpliwość dla nooba ;]

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