Läste Computer Sweden idag där det fanns en anst.annons där de som kunde hitta fem fel i koden nedan kunde söka tjänsten. Om någon hittar svaren så ska jag publicera företaget som söker en C++ utvecklare ;) De tre första är riktiga fel, 4, 5 och 6 mer "är det verkligen vettigt?": Kan man inte bara tilldela tal 0? >Man kan bara tilldela tal 0: Vi kan väl sammanfatta felen så här då: >1. T& Clone(T a_src) // borde vara T& Clone(const &T a_src) Kommer den då inte att kopiera värdet när man tilldelar den? >Kommer den då inte att kopiera värdet när man tilldelar den?Finn fem fel i koden
<code>
template <typename T>
T& Clone(T a_src)
{
T ret = 0;
T* tmp = NULL;
tmp = new T(a_src);
ret = *tmp;
return ret;
}
</code>
(jag lovar att jag inte ska stjäla svaren och söka jobbet :))Sv: Finn fem fel i koden
1. ret är en template, och inget garanterar att operator= är definierad för en int.
2. tmp deleta:s inte.
3. Man kan (ska) inte returnera en referens till en lokal variabel.
4. Varför NULL istället för tilldelning direkt, och varför tilldelning till tmp istället för tilldelning till ret direkt?
5. Om det nu finns en operator(T), varför inte använda den direkt i kod? Varför ha en Clone-funktion öht?
6. a_src bör väl skickas som en const &T?Sv:Finn fem fel i koden
T ret = 0;
Jag tror om koden avser klasser är denna raden ogiltlig.
Är det "korrekt" svaret något sådant här?
template <typename T>
T* Clone(const T& a_src)
{
return new T(a_src);
}
Sv: Finn fem fel i koden
Nix, alla typer som har en konstruktor som accepterar 0 fungerar fint.
Alla följande typer fungerar
struct C {
C(int);
};
struct D {
D(char*);
};
struct E {
E& operator=(int);
};
>Är det "korrekta" svaret något sådant här?
Nej, det finns nog inget korrekt svar. Clone är funktion som man använder om det finns anledning att skilja på copy och clone. Ett exempel skulle kunna vara att du har en klass som innehåller en pekare till ett annat objekt. copy innebär då att att det nya objektet har samma pekare medan clone innebär att man får en ny pekare.
struct C {
C(int a) : m(a) { };
int m;
};
struct D {
D(int a) : mp(new C(a)) { }
D D(const D& a) { D tmp; tmp.mp = a.mp; return tmp; } // copy constructor
D Clone() { return D(mp->m); }
protected:
D() : mp(NULL) { }
private:
C* mp;
};
main() {
D a(3);
D b = a; // a och b delar nu samma object C
D c = a.Clone(); // a och c innehåller samma värde fast med olika object C
}
(Vet att koden ovan skapar minnesläckor men det är bara ett exempel)
En annan konstighet är att Clone är en "fri" funktion (dvs ej medlem). Som jag beskrev ovan är ju anledningen till att man har en Clone att man behöver fixa något internt i klassen och det kan ju inte en "fri" funktion göra om den inte är friend. Men i det här fallet är det ju en template och har för mig att man inte kan ha friend templates.
template <typename T>
T Clone(const T& a) { return T(); }
Sv:Finn fem fel i koden
1. T& Clone(T a_src) // borde vara T& Clone(const &T a_src)
2. T ret = 0; // fel eftersom man inte kan förutsätta att typen har en ctr som hanterar tilldelningen
3. tmp = new T(a_src); // en Clone som använder implicit shallow copying?
4. ret = *tmp; // återigen en implicit operation
5. tmp's minne frigörs inte
6. return ret; // returnerar lokala instanser
Jag lovade ju länken till företaget som sökte C++ utvecklare, så här är den:
http://csjobb.idg.se/Arbetsgivaren.nsf/All/B4F8D2674AEC0687C12572D400287B68?OpenDocument&id=2Sv: Finn fem fel i koden
T Clone(const T& a_src);Sv:Finn fem fel i koden
Är det inte bättre att retunera en pekare?Sv: Finn fem fel i koden
I teorin ja men det finns inte något alternativ eftersom du kanske inte vill tilldela den till en variabel.
Clone(x).SomeMethod();
I praktiken lär kompilatorn dessutom använda Return-value-Optimization (RVO) vilket innebär att kod som:
T func() {
T x;
x = ...
return x;
}
a = func();
görs om till
void func(T& x) {
x = ...
}
T a;
func(a);
>Är det inte bättre att retunera en pekare?
Nix, vi pratar c++ och där använder man (nästan) aldrig pekare.