2010-02-06 9 views
9

Supponiamo di voler passare un oggetto temporaneo in una funzione. C'è un modo per farlo in 1 linea di codice contro 2, con una struct?Un modo semplice per passare la struttura temporanea in base al valore in C++?


con una classe, non posso fare:

class_func(TestClass(5, 7)); 

dato:

class TestClass 
{ 
private: 
    int a; 
    short b; 

public: 
    TestClass(int a_a, short a_b) : a(a_a), b(a_b) 
    { 
    } 

    int A() const 
    { 
     return a; 
    } 

    short B() const 
    { 
     return b; 
    } 
}; 

void class_func(const TestClass & a_class) 
{ 
    printf("%d %d\n", a_class.A(), a_class.B()); 
} 

Ora, come faccio a farlo con una struct? Il più vicino che ho è:

test_struct new_struct = { 5, 7 }; 
struct_func(new_struct); 

dato:

struct test_struct 
{ 
    int a; 
    short b; 
}; 

void struct_func(const test_struct & a_struct) 
{ 
    printf("%d %d\n", a_struct.a, a_struct.b); 
} 

L'oggetto è più semplice, ma mi chiedo se c'è un modo per fare l'inizializzazione membro struct perfettamente in linea con la chiamata di funzione , senza dare alla struct un costruttore. (Non voglio un costruttore. Tutta la ragione che sto usando una struct è quello di evitare i get/set convenzioni classe boilerplate in questo caso isolato.)

+3

È ancora possibile scrivere un kee costruttore ping le variabili membro pubbliche. Quindi non hai bisogno di metodi get/set. C'è qualche problema nel farlo? – Naveen

+0

Intendevi realizzare l'inizializzazione della struct in C? In C++ una struct può anche fare qualunque cosa tu stia facendo nella classe. – sand

risposta

0

Io non sono esperto di C++, ma non potevi basta inserire la dichiarazione di creazione all'interno dell'elenco degli argomenti della chiamata di funzione?

+0

No, alcuni compilatori consentono questo tipo di cose ed è in C++ 0x (§5.2.3/3) ma non è attualmente standard. – Potatoswatter

2

È possibile farlo nello stesso modo in cui si fa con la classe. Basta dare alla tua struct un costruttore e puoi crearlo in linea proprio come la struct. Le tue obiezioni sull'utilizzo di un costruttore sono infondate. La differenza principale tra una classe e una struttura è la visibilità predefinita associata ad essa. Per le classi, è privato; per le strutture, pubblico. Non esiste un "boilerplate" e non è necessario rispettare le "convenzioni" che non si desidera.

+0

@Terry Mahaffey, è possibile utilizzare l'inizializzazione delle parentesi graffe con una classe. I vincoli sono gli stessi di struct.La differenza tra 'struct' e' class' keyword * è * default only visibility (per membri e classi base). Puoi anche mescolare le parole chiave: 'struct t {}; classe t v; '. – avakar

+0

Sì, hai ragione. Pensavo che solo le strutture potessero essere POD per qualche ragione. Ritiro il mio commento –

0

Le strutture possono anche avere costruttori, quindi è possibile fare la stessa cosa con l'esempio di classe.

4

Questo è possibile nel C++11 standard. In sostanza, si è in grado di fare questo:

struct_func(test_struct{5, 7}); 

Questo è già disponibile in GCC a partire dalla versione 4.4.

+0

In realtà, non hanno nemmeno bisogno di dichiarare in modo esplicito il tipo, a meno che non ci sia ambiguità circa i tipi che possono essere creati dalla lista init rinforzato: '#include struct S { int i; doppia d; }; void f (S s) { std :: cout << s.i << '' << s.d << std :: endl; } int main (int, char **) { f ({7, 42}); } 'Non credo che mi sarei mai trovato senza un'inizializzazione uniforme o tutti gli altri enormi aggiornamenti fatti in C++ 11 che dò per scontati. –

8

Un'alternativa a fornire un costruttore nella vostra struct, sarebbe quello di fornire un make_xxx funzione libera:

struct Point {int x; int y;}; 

Point makePoint(int x, int y) {Point p = {x, y}; return p;} 

plot(makePoint(12, 34)); 

Uno dei motivi per cui si potrebbe voler evitare costruttori in struct è quello di permettere brace-inizializzazione array di le strutture:

// Not allowed when constructor is defined 
const Point points[] = {{12,34}, {23,45}, {34,56}}; 

vs

const Point points[] = {Point(12,34), Point(23,45), Point(34,56)}; 
+1

Si noti che in C++ 11, l'uso può utilizzare l'inizializzazione del brace anche se il costruttore 'Point' è definito. In tal caso, gli argomenti all'interno delle parentesi verranno passati al costruttore. Questa funzione è chiamata [Uniform Initialization] (https://en.wikipedia.org/wiki/C%2B%2B11#Uniform_initialization). –

Problemi correlati