Em C #, há um açúcar de sintaxe agradável para campos com getter e setter. Além disso, gosto das propriedades implementadas automaticamente, que me permitem escrever
public Foo foo { get; private set; }
Em C ++ eu tenho que escrever
private:
Foo foo;
public:
Foo getFoo() { return foo; }
Existe algum conceito desse tipo no C ++ 11, permitindo-me ter algum açúcar de sintaxe nisso?
Respostas:
Em C ++, você pode escrever seus próprios recursos. Aqui está um exemplo de implementação de propriedades usando classes sem nome. Artigo da Wikipedia
Você pode escrever seus próprios getters e setters no local e, se desejar acesso de membro da classe titular, poderá estender este código de exemplo.
fonte
_alpha
para a variável privada ealpha
para a referência.sizeof(Foo)
.C ++ não tem isso integrado, você pode definir um modelo para imitar a funcionalidade das propriedades:
Para definir uma propriedade :
Para implementar um getter / setter personalizado, basta herdar:
Para definir uma propriedade somente leitura :
E para usá-lo na aula
Owner
:Você pode definir alguns dos itens acima em macros para torná-lo mais conciso.
fonte
virtual
é desnecessário para a maioria dos casos de uso, uma vez que é improvável que uma propriedade seja usada polimorficamente.Não há nada na linguagem C ++ que funcione em todas as plataformas e compiladores.
Mas se você estiver disposto a quebrar a compatibilidade de plataforma cruzada e se comprometer com um compilador específico, você pode usar essa sintaxe, por exemplo, no Microsoft Visual C ++ ,
fonte
Você pode emular getter e setter, até certo ponto por ter um membro do tipo dedicado e substituindo
operator(type)
eoperator=
por isso. Se é uma boa ideia é outra questão e irei à+1
resposta de Kerrek SB para expressar minha opinião sobre isso :)fonte
friend
ao proprietário do campo.Talvez dê uma olhada na classe de propriedade que montei nas últimas horas: /codereview/7786/c11-feedback-on-my-approach-to-c-like-class-properties
Ele permite que você tenha propriedades que se comportam assim:
fonte
Com C ++ 11, você pode definir um modelo de classe Property e usá-lo assim:
E aqui está o template da classe Property.
fonte
C::*
significa Eu nunca vi nada parecido antes?C
. Isso é semelhante a um ponteiro de função simples, mas para chamar a função de membro, você precisa fornecer um objeto no qual a função é chamada. Isso é feito com a linhaitsObject->*itsSetter(theValue)
do exemplo acima. Veja aqui uma descrição mais detalhada deste recurso.Como muitos outros já disseram, não há suporte embutido na linguagem. No entanto, se o seu objetivo é o compilador Microsoft C ++, você pode aproveitar as vantagens da extensão específica da Microsoft para propriedades documentadas aqui.
Este é o exemplo da página vinculada:
fonte
Não, C ++ não tem conceito de propriedades. Embora possa ser difícil definir e chamar getThis () ou setThat (value), você está fazendo uma declaração ao consumidor desses métodos de que alguma funcionalidade pode ocorrer. Acessar campos em C ++, por outro lado, informa ao consumidor que nenhuma funcionalidade adicional ou inesperada ocorrerá. As propriedades tornariam isso menos óbvio, pois o acesso à propriedade à primeira vista parece reagir como um campo, mas na verdade reage como um método.
À parte, eu estava trabalhando em um aplicativo .NET (um CMS muito conhecido) tentando criar um sistema de associação do cliente. Devido à maneira como eles usaram propriedades para seus objetos de usuário, ações foram disparadas que eu não havia previsto, fazendo com que minhas implementações fossem executadas de maneiras bizarras, incluindo recursão infinita. Isso acontecia porque seus objetos de usuário faziam chamadas para a camada de acesso a dados ou algum sistema de cache global ao tentar acessar coisas simples como StreetAddress. Todo o seu sistema foi baseado no que eu chamaria de abuso de propriedades. Se eles tivessem usado métodos em vez de propriedades, acho que teria descoberto o que estava errado muito mais rapidamente. Se eles tivessem usado campos (ou pelo menos feito suas propriedades se comportassem mais como campos), acho que o sistema teria sido mais fácil de estender e manter.
[Editar] Mudei meus pensamentos. Tive um dia ruim e comecei a reclamar um pouco. Essa limpeza deve ser mais profissional.
fonte
Com base em https://stackoverflow.com/a/23109533/404734, aqui está uma versão com um getter público e um setter privado:
fonte
Esta não é exatamente uma propriedade, mas faz o que você quiser de maneira simples:
Aqui, o grande X se comporta como
public int X { get; private set; }
na sintaxe C #. Se você deseja propriedades completas, fiz uma primeira tentativa para implementá-las aqui .fonte
X
do novo objeto ainda apontará para o membro do objeto antigo, porque ele é apenas copiado como um membro ponteiro. Isso é ruim por si só, mas quando o objeto antigo é excluído, há corrupção de memória em cima dele. Para fazer isso funcionar, você também teria que implementar seu próprio construtor de cópia, operador de atribuição e construtor de movimento.Você provavelmente sabe disso, mas eu simplesmente faria o seguinte:
Essa abordagem é simples, não usa truques inteligentes e dá conta do recado!
O problema, porém, é que algumas pessoas não gostam de prefixar seus campos privados com um sublinhado e, portanto, não podem realmente usar essa abordagem, mas, felizmente, para aqueles que usam, é realmente simples. :)
Os prefixos get e set não adicionam clareza à sua API, mas os tornam mais detalhados e a razão pela qual eu não acho que eles adicionam informações úteis é porque quando alguém precisa usar uma API se a API faz sentido, ela provavelmente vai perceber o que é faz sem os prefixos.
Mais uma coisa, é fácil entender que essas são propriedades porque
name
não é um verbo.Na pior das hipóteses, se as APIs forem consistentes e a pessoa não perceber que
name()
é um acessador ename(value)
um modificador, ela só terá que procurar uma vez na documentação para entender o padrão.Por mais que eu ame C #, acho que C ++ não precisa de propriedades!
fonte
foo(bar)
(em vez do mais lentofoo = bar
), mas seus acessores não têm nada a ver com propriedades ...foo(bar)
vez dofoo=bar
que pode ser alcançado com umvoid foo(Bar bar)
método mutador em uma_foo
variável de membro.Não .. Mas você deve considerar se é apenas a função get: set e nenhuma tarefa adicional pré-formada dentro dos métodos get: set, apenas torná-la pública.
fonte
Eu coletei as ideias de várias fontes C ++ e as coloquei em um exemplo legal, ainda bastante simples, para getters / setters em C ++:
Resultado:
Você pode testá-lo online aqui: http://codepad.org/zosxqjTX
fonte
Sua classe realmente precisa impor alguma invariante ou é apenas um agrupamento lógico de elementos de membro? Se for o último, você deve considerar tornar a coisa uma estrutura e acessar os membros diretamente.
fonte
Há um conjunto de macros escritas aqui . ISTO tem declarações de propriedade convenientes para tipos de valor, tipos de referência, tipos somente leitura, tipos fortes e fracos.
fonte