2012-05-21 602 views
6

Estoy haciendo la programación de Box2D, y cara a cara, soy un novato total para C++ y C. Soy un chico de Objective-C, y es por eso que se está volviendo realmente difícil para mí entender el lenguaje. Especialmente:Es C's -> equivalente a la notación de puntos en Objective-C

-> 

Básicamente entiendo que esto se utiliza para hacer referencia a diferentes métodos o funciones o variables/propiedades como a continuación:

body->GetWorld()->DestroyBody(body); 

Así es esto equivale a puntear la notación en Objective-C:

// made up example 
[body.world destroyBody]; 

o

[self destroyBody:body.world]; 

¿O algo similar? Realmente no entiendo esto. ¿Puede alguien darme un aviso sobre lo que es esto? ¡Gracias!

+1

AFAIK Objective-C también tiene '->'. –

+0

'->' es de C. – Pubby

+0

Ah, vale, es de C. – MCKapur

Respuesta

10

No sé Objective-C, pero puedo explicar la diferencia entre -> y . en C y C++, espero que ayude.

. es un operador que le permite acceder al miembro de la instancia de struct/class. a->b es lo mismo que (*a).b - por lo que primero desreferencia el puntero y luego accede al miembro de la instancia al que apuntaba el puntero.

Además, hay un caso que Luchian ha mencionado - sobrecarga de operator->() de la clase dada. En caso de que la clase que está utilizando sobrecargue este operador, el comportamiento será diferente, definido por la clase: puede devolver virtualmente todo lo que quiera.

+0

ok que figuras, gracias por la respuesta! Voy a marcar 9 minutos, eso es cuando puedo hacerlo – MCKapur

+1

@RohanKapur esto no siempre es cierto. –

+0

No existe una sobrecarga del operador en el objetivo C;) –

4

No sé mucho acerca de Objective-C, pero puedo tratar de darle un poco de ayuda sobre C++: suponiendo que se define una clase Foo en C++, con un método bar():

class Foo 
{ 
public: 
    void bar(); 
    ... 
}; 

Si asignar una instancia de Fooen la pila, se utiliza la notación de punto (.) para llamar al método bar():

Foo f; 
f.bar(); 

Si usted tiene un puntero a una instancia de Foo, utilizará la flecha notación (->) para llamar al método bar():

Foo* pf; // must point to some instance of Foo 
pf->bar(); 

(Para complicar las cosas, también hay referencias, que tienen sintaxis de valor y semántica de puntero: si tiene una referencia a Foo (p. ej. Foo& f) todavía se utiliza la notación de puntos:. f.bar();)

+2

la asignación de pila y montón no tiene nada que ver con el uso de '->' o '.': lo único que importa es el tipo de expresión que se utiliza. – akappa

+0

@akappa: Acabo de dar algunos ejemplos concretos para intentar explicar el concepto de sintaxis punto vs. flecha. Sé que si asigna 'Foo' en la pila (' Foo f; ') y luego tiene un puntero al mismo' Foo' ('Foo * pf = & f;') la sintaxis sigue siendo 'pf-> bar() ; '. Intento ser lo más simple posible en las explicaciones para los principiantes del lenguaje y evitar la confusión. –

+0

"Todo debe hacerse lo más simple posible, pero no más simple". Hacer ejemplos de algo general está bien, intentar simplificar algo enumerando solo algunos ejemplos es terriblemente incorrecto y potencialmente engañoso, especialmente si no se dice explícitamente que esos son solo ejemplos. Por ejemplo, podría escribir algo como 'Foo * x = new Foo(); Foo & y = * x; y-> método(); 'o' Foo x; Foo * y = & x; y.method(); 'y preguntándome por qué no funciona. – akappa

2

. se utiliza para acceder a miembros de objetos, -> se utiliza para los miembros de acceso a través de un puntero. Generalmente.operator -> puede sobrecargarse, lo que significa que también se puede utilizar en objetos:

struct X 
{ 
    X* other; 
    X* operator->() {return other;} 
}; 

X x; 
x->other; 

En este caso, x->other no Reffer a x.other, pero a x.other.other. : D

+0

Buen punto sobre la sobrecarga del operador, lo extrañé totalmente. – Griwes

+0

No existe una sobrecarga del operador en el objetivo C;) –

+0

@VictorCarmouze no dice que hay ... –

2

No, usar . para acceder a las propiedades de Objective-C no es lo mismo que -> o . para acceder a los miembros de estructura y clase en C y C++.

El descriptor de acceso de propiedad Objective-C funciona en valores del tipo id (que es un tipo de puntero), pero utiliza convenciones de nomenclatura especiales para decidir lo que realmente hace. Puede acceder directamente a un miembro de datos de propiedades, por lo que es similar al -> para el acceso de los miembros de datos. O puede buscar funciones especiales para obtener y/o establecer el valor de la propiedad, en cuyo caso se trata de azúcar de sintaxis para el envío de un mensaje.

Excepto en el caso de sobrecarga del operador en C++, -> es siempre lo mismo que eliminar un apuntador y luego acceder al miembro al que se hace referencia. a->b es equivalente a (*a).b. b puede ser un miembro de datos para una función miembro, pero el miembro al que se tiene acceso tendrá el nombre exacto al que se hace referencia en b, no alguna mutación de la misma basada en ninguna convención de nomenclatura especial. Si b nombra una función miembro, entonces puede ser una función virtual, que tiene algunas similitudes con, pero no es lo mismo que, envía mensajes en Objective-C. b también puede ser una función de miembro sobrecargado en C++ que no tiene equivalente en Objective-C.

La adición de la sintaxis . para acceder a las propiedades del objeto en Objective-C infringe el principio de diseño de Objective-C de que las nuevas características deben parecer nuevas. Utilizando @, la sintaxis de envío de mensajes [] y las palabras clave especiales para definir objetos Objective-C son ejemplos donde Objective-C previamente siguió este diseño principal.

1

Este es el código object-c.

@interface Foo : NSObject 
{ 
    NSInteger _a; 
} 
@property (nonatomaic, assign) NSInteger a; 
@end 

@implement Foo 
@synthesize a = _a; 
@end 

Usted sabe la frase '@synthesize'. @synthesize crear códigos de abajo.

- (NSInteger)a 
{ 
    return _a; 
} 


- (void)setA:(NSInteger)aa 
{ 
    return _a = aa; 
} 

Accedemos a la propiedad a.

void main() 
{ 
    Foo foo = [[Foo alloc] init]; 
    foo.a = 1; 
} 

Must foo.a asignado como 1. Pero el llamado compilador como bramido.

void main() 
{ 
    Foo foo = [[Foo alloc] init]; 
    [foo setA:1]; 
} 

foo.a = 1 y [foo setA: 1] es lo mismo. foo.a = 1 llamadas [foo setA: 1].

de fuelles, escrito en C.

class Foo 
{ 
private: 
    int _a; 
public: 
    int getA(); 
    void setA(const int aa); 
}; 

int Foo::getA() 
{ 
    return _a; 
} 
void Foo::setA(const int aa) 
{ 
    _a = aa; 
} 

// local allocation example. 

void main() 
{ 
    Foo foo; 
    foo.setA(1); 
} 

// Heap allocation example. 
void main() 
{ 
    Foo *foo = new Foo(); 
    foo->setA(1); 
    delete foo; 
} 

// Pointer (like object objectve-c). 
void main() 
{ 
    Foo foo1; 
    foo1.setA(1); 

    Foo *foo2 = &foo1; 
    foo2->setA(2); 

    printf("result>>> %d, %d", foo1.a, foo2->a); 
} 

result>>> 2, 2 

foo1.a y foo2-> a es 2 también. Ejemplo de Objectve-C a continuación.

void main() 
{ 
    Foo *foo1 = [[Foo alloc] init]; 
    foo1.a = 1; 

    Foo *foo2 = foo1; 
    foo2.a = 2; 

    NSLog(@"result>>> %d, %d", foo1.a, foo2.a); 
} 

result>>> 2, 2 

Que tengas un buen día. Gracias.

Cuestiones relacionadas