-
May 31st, 2018, 01:59 PM
#1
mask copy constructor
About this code, I'm not understanding because it has been defined this copy constructor
"Anfiteatro(const Anfiteatro &)", I think to avoid to have similar events:
Anfiteatro aa=a2;
Compilator detects copy constructor with this header and it make nothing because function is not defined, but why!?!? What is need?! But I'n not understanding.
this is code:
compito.h
Code:
#include <iostream>
using namespace std;
class Anfiteatro{
struct elemento{
int numMatt;
elemento * succ;
};
elemento* testa;
// mask copy constructor
Anfiteatro(const Anfiteatro &);
// funzioni di utilita'
void elimina();
public:
// PRIMA PARTE
Anfiteatro(int);
bool aggiungiMattonelle(int);
void aggiungiColonna(int);
friend ostream& operator<<(ostream&, const Anfiteatro&);
// SECONDA PARTE
bool togliColonna(int);
Anfiteatro& operator= (const Anfiteatro&);
~Anfiteatro(){elimina();}
};
compito.cpp
Code:
#include "compito.h"
// funzione di utilita'
void Anfiteatro::elimina(){
elemento* p=testa;
while(testa!=0){
testa=p->succ;
delete p;
p=testa;
}
}
// --- PRIMA PARTE ---
Anfiteatro::Anfiteatro(int n){
if (n < 0)
n=0;
testa = 0;
elemento* q;
for (int i=0; i<n; i++){
q = new elemento;
q->numMatt = 0;
q->succ = testa;
testa = q;
}
}
bool Anfiteatro::aggiungiMattonelle(int k) {
if (k < 0)
k = 0;
elemento* pmin = testa;
if (testa == 0)
return false;
for (elemento* p = testa; p != 0; p = p->succ)
if ( p->numMatt < pmin->numMatt )
pmin = p;
pmin->numMatt += k;
return true;
}
void Anfiteatro::aggiungiColonna(int k) {
if (k <0)
k = 0;
elemento *p, *q;
for (p = testa; p != 0; p = p->succ)
q = p;
p = new elemento;
p->succ = 0;
p->numMatt = k;
if (testa == 0)
testa = p;
else
q->succ = p;
}
ostream& operator<<(ostream& os, const Anfiteatro& a){
os<<'<';
for (Anfiteatro::elemento* p=a.testa; p!=0;p=p->succ){
os<<'['<<p->numMatt<<']';
if (p->succ!=0)
os<<',';
}
os<<'>';
return os;
}
// --- SECONDA PARTE ---
bool Anfiteatro::togliColonna(int n) {
elemento* p, *q;
int cont = 1;
if (n <= 0)
return false;
for (p = testa; p != 0 && cont<n; p = p->succ) {
q = p;
cont++;
}
if (p == 0)
return false;
if (p == testa)
testa = p->succ;
else
q->succ = p->succ;
delete p;
return true;
}
Anfiteatro& Anfiteatro::operator=(const Anfiteatro& a){
if ( this != &a){
elimina();
testa=0;
elemento *q;
for (elemento* p=a.testa; p!=0;p=p->succ){
elemento* r=new elemento;
r->numMatt = p->numMatt;
r->succ=0;
if (testa==0)
testa=r;
else
q->succ=r;
q=r;
}
}
return *this;
}
main.cpp
Code:
#include "compito.h"
#include <iostream>
using namespace std;
int main()
{
cout << endl << "--- PRIMA PARTE ---" << endl;
cout<<"\nChiamata al costruttore"<<endl;
Anfiteatro a(4);
cout<<a<<endl;
cout << "Chiamata alla funzione aggiungiMattonelle()" << endl;
a.aggiungiMattonelle(7);
cout << a << endl;
cout << "Altra chiamata alla funzione aggiungiMattonelle()" << endl;
a.aggiungiMattonelle(12);
cout << a << endl;
cout << "\nChiamata alla funzione aggiungiColonna()" << endl;
a.aggiungiColonna(8);
cout << a << endl;
cout << endl << "--- SECONDA PARTE ---" << endl;
cout << endl << "Chiamata alla funzione togliColonna()" << endl;
a.togliColonna(1);
cout << a << endl;
{
cout << endl << "Test dell'operatore assegnamento " << endl;
Anfiteatro a1(2);
cout << "a1 ( *prima* dell'assegnamento ) " << a1 << endl;
a1 = a;
cout << "a1 ( *dopo* l'assegnamento ) " << a1 << endl;
cout << endl;
cout << "Test del distruttore (a1 sta per essere distrutto)" << endl;
}
return 0;
}
thanks
Last edited by zio_mangrovia; June 8th, 2018 at 01:03 AM.
-
May 31st, 2018, 04:53 PM
#2
Re: mask copy constructor
This is OK. Declaring the copy constructor private without defining it, is an old trick to prevent copies. (in modern C++, "= delete" can be used instead).
The Anfiteatro class has a pointer (testa) that needs to be deleted in the destructor. If shallow copies were allowed, it would be dangerous because the destructor may then delete the same memory more than once.
Last edited by TubularX; May 31st, 2018 at 05:10 PM.
-
June 1st, 2018, 12:33 AM
#3
Re: mask copy constructor
Originally Posted by TubularX
If shallow copies were allowed, it would be dangerous because the destructor may then delete the same memory more than once.
To make an example:
If I defined "Anfiteatro dest=source",
default copy constructor should to copy testa pointer content of source class object to testa pointer of dest class object,
so both class objects will share the same area memory and the destructor may then delete the same memory more than once.
Is't right?
-
June 1st, 2018, 12:45 AM
#4
Re: mask copy constructor
I have another question about this code please.
The "constructor" Anfiteatro::Anfiteatro(int), I could declare it as Anfiteatro::Anfiteatro(const int) because value which is passed to constructor is always numeric costant.
Thanks
-
June 1st, 2018, 01:37 AM
#5
Re: mask copy constructor
Originally Posted by zio_mangrovia
I have another question about this code please.
The "constructor" Anfiteatro::Anfiteatro(int), I could declare it as Anfiteatro::Anfiteatro(const int) because value which is passed to constructor is always numeric costant.
Thanks
It doesn't matter and is not needed.
just because the int argument is always passed by value (creating a copy)!
Victor Nijegorodov
-
June 1st, 2018, 03:26 AM
#6
Re: mask copy constructor
Right, the copied object will have a pointer that points to the same memory.
If you really want to make a copy, you would either need to make a deep copy (i.e. make sure the memory pointed to is copied as well), or use a reference counting smart pointer like std::shared_ptr. Whether that is a good idea or not in this case is another question.
You can make the int parameter const if you want to express intent that the value must not be modified. But that's not currently the case, because of the line "n=0;" inside the constructor.
-
June 8th, 2018, 01:04 AM
#7
Re: mask copy constructor
I don't understand because main.cpp says:
Code:
#include "compito.h"
#include <iostream>
using namespace std;
Compito.h contains just both #include <iostream> and using namespace std;
I thought it was necessary #include "compito.h"
-
June 8th, 2018, 02:12 AM
#8
Re: mask copy constructor
Originally Posted by zio_mangrovia
I don't understand because main.cpp says:
Code:
#include "compito.h"
#include <iostream>
using namespace std;
Compito.h contains just both #include <iostream> and using namespace std;
I thought it was necessary #include "compito.h"
If that is what Compito.h contains, then either you don't need to include this in .cpp - or you don't need the #include and using statements in .cpp. However note that for good practice, using namespace shouldn't be part of a .h.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|