2009-02-06 18 views
7

Zmieniam starą procedurę, która używała parametru integer tak, że teraz przyjmuje referencję do obiektu. Miałem nadzieję, że kompilator powie mi, skąd funkcja jest wywoływana (ponieważ typ parametru jest nieprawidłowy), ale obiekt ma konstruktor, który pobiera liczbę całkowitą, więc zamiast niepowodzenia, kompilator tworzy obiekt tymczasowy, przekazując go integer i przekazuje odwołanie do procedury. Przykładowy kod:Jak mogę powiedzieć kompilatorowi, aby nie tworzył obiektu tymczasowego?

class thing { 
    public: 
    thing(int x) { 
     printf("Creating a thing(%d)\n", x); 
    } 
}; 

class X { 
    public: 
    X(const thing &t) { 
     printf("Creating an X from a thing\n"); 
    } 
}; 


int main(int, char **) { 
    thing a_thing(5); 
    X an_x(6); 
    return 1; 
} 

Chcę linia do X an_x(6) nie skompilować, ponieważ nie ma X konstruktor, która pobiera int. Ale to nie skompilować, a wyjście wygląda następująco:

Creating a thing(5) 
Creating a thing(6) 
Creating an X from a thing 

Jak mogę utrzymać konstruktora thing(int), ale zabronić tymczasowy obiekt?

Odpowiedz

11

Użyj słowa kluczowego explicit w konstruktorze thing.

class thing { 
public: 
    explicit thing(int x) { 
     printf("Creating a thing(%d)\n", x); 
    } 
}; 

Uniemożliwi to kompilatorowi niejawne wywołanie konstruktora thing, gdy znajdzie liczbę całkowitą.

+0

Zobacz tę odpowiedź: http://stackoverflow.com/questions/121162/what-does-the-explicit-keyword-in-c-mean – Skizz

+0

Perfect - Piszę kod C++ przez około 15 lat i mam nigdy nie słyszałem o jawnym słowie kluczowym. Dzięki! –

+0

Powiązane pytanie - czy możesz użyć jawnego słowa kluczowego w metodzie, która nie jest konstruktorem? –

1

explicit kluczowe działa idealnie w moim przykładzie, ale później zdałem sobie sprawę, że mój kod prawdziwy świat została braku na przeciążonej metody, a nie konstruktor. (Moja wina za zadawanie pytań, które były podobne do, ale nie takie same, jak mój rzeczywisty problem.) Jak Mark Ransom wskazał w komentarzach do zaakceptowanej odpowiedzi, explicit działa tylko na konstruktorach. Wymyśliłem obejście, które rozwiązało mój problem, więc pomyślałem, że opublikuję go tutaj. Nowy przykładowy kod:

class thing { 
    public: 
    thing(int x) { 
     printf("Creating a thing(%d)\n", x); 
    } 
}; 

class X { 
    public: 
    void do_something(const thing &t) { 
     printf("Creating an X from a thing\n"); 
    } 
}; 


int main(int, char **) { 
    thing a_thing(5); 
    X an_x; 
    an_x.do_something(6); 
    return 1; 
} 

Kod ten pokazuje ten sam efekt jak w oryginalnym kodzie, ale nie mogę używać explicit go naprawić. Zamiast tego, dodałem prywatną metodę, która zajmuje int:

private: 
    void do_something(int x); 

Teraz kompilator nie tworzy tymczasowy obiekt, daje błąd, ponieważ staram się wywołać prywatną metodę spoza klasy.

+0

w C++ 1x, będziemy mogli napisać void do_something (int x) = delete; już działa w bagażniku gcc svn. –

+0

@ Graeme Perrow. Jawny powinien nadal działać w przypadku, gdy się zarysujesz. Oznacza to, że skonstruowanie konstruktora thing spowoduje błąd kompilatora. Czy to dlatego, że nie masz dostępu do klasy rzeczy, aby ją zmodyfikować? @litb czy zaczęliśmy nazywać to C++ 1x teraz? Czy tęskniłem za notatką? – zdan

+0

@zdan: masz rację. Zastanawiałem się, jak zmodyfikować klasę X i nie myślałem o modyfikacji klasy rzeczy. To robi to, czego potrzebuję. Dzięki! –

Powiązane problemy