2010-02-26 4 views
0

struct Foo { char * DataPtr; };Const-Correctness sur la valeur de retour complexe

class ISomeInterface { 
public: 
    Foo GetFoo() const; 
    Foo GetFoo(); 
}; 

Le Foo::DataPtr est un pointeur vers un tampon interne de l'objet behing ISomeInterface. Est-il un moyen de s'assurer que le Foo::DataPtr retourné par la version const de ISomeInterface::GetFoo est un const char *?

+0

Foo :: DataPtr est un type donc char const * - que voulez-vous dire - si vous voulez que vous renvoyez char const * alors déclarez simplement comme char const * GetFoo() cons; – Mark

+0

Foo :: DataPtr n'est pas un type mais un membre de la structure Foo avec le type char * (ou const char *). Dans le monde réel, Foo est plus complexe, donc retourner un char * (ou const char *) n'est pas une option. –

Répondre

5

Vous avez besoin d'un

struct ConstFoo { 
    const char* DataPtr; 
}; 

pour cela. La const de C++ n'est pas transitive. (Ce qui est aussi la raison pour laquelle vous avez iterator et const_iterator.)

+0

Donc, pas de solution simple alors. Merci. –

1

A struct

struct Foo { 
    char * DataPtr; 
} 

n'est pas la même chose que

struct Foo { 
    const char * DataPtr; 
} 

de sorte que vous ne pouvez pas différencier la façon dont vous le souhaitez.

Vous pouvez faire la const GetFoo() retourner un const objet Foo (que je soupçonne est pas ce que vous voulez, car il fera toutes les variables membres const), ou faire une autre struct avec un const char * DataPtr (par exemple FooConst) qui est retourné sur l'appel const.

+0

En fait, je pourrais utiliser un objet const, puisqu'il s'agit juste d'un objet de données censé être en lecture seule. Je ne savais pas si je pouvais utiliser const sur un objet, ou juste sur des références et des pointeurs. –

0

Vous pouvez essayer de changer la conception de votre Foo et « cacher » l'acess à DataPtr derrière les fonctions. Par exemple:

class Foo { 
    char * DataPtr; 
public: 
    //just some examples 
    void doThis() const {} 
    void doThat() {} 
}; 

class ISomeInterface { 
public: 
    const Foo GetFoo() const { return Foo(); } 
    Foo GetFoo() { return Foo(); } 
}; 

... 

const Foo foo1 = ISomeInterface().GetFoo(); 
foo1.doThis(); 
foo1.doThat(); //error 
Foo foo2 = ISomeInterface().GetFoo(); 
foo2.doThis(); 
foo2.doThat(); 

Fournir des fonctions qui définissent les opérations sont const et ceux qui ne sont pas, vous pouvez éviter de dupliquer votre Foo et obtenir les restrictions const-exactitude vous semblez viser.

+0

Merci pour la réponse. J'espérais que ça marcherait sans ça, pour éviter les encombrements inutiles. –