Eu encontrei esta linha de código em uma classe que eu tenho que modificar:
::Configuration * tmpCo = m_configurationDB;//pointer to current db
e não sei exatamente o que significa dois pontos duplos anexado ao nome da classe. Sem isso, eu leria: declaração de tmpCo
como um ponteiro para um objeto da classe Configuration
... mas os dois pontos duplos anteriores me confundem.
Eu também encontrei:
typedef ::config::set ConfigSet;
c++
syntax
namespaces
scope-resolution
global-namespace
rmbianchi
fonte
fonte
::
meios nus referenciam a variável do namespace global / anônimo.Respostas:
Isso garante que a resolução ocorra no namespace global, em vez de iniciar no namespace em que você está atualmente. Por exemplo, se você tivesse duas classes diferentes chamadas
Configuration
como tais:Basicamente, ele permite percorrer o espaço para nome global, já que seu nome pode ser derrotado por uma nova definição dentro de outro espaço para nome, nesse caso
MyApp
.fonte
::Configuration::doStuff(...)
::
dois termos intermediários se referem ao espaço para nome ou classe e seu membro. Mas e o primeiro?O
::
operador é chamado de operador de resolução de escopo e, justamente isso, resolve o escopo. Portanto, prefixando um nome de tipo com isso, ele diz ao seu compilador para procurar no espaço de nomes global pelo tipo.Exemplo:
fonte
Muitas respostas razoáveis já. Vou abordar uma analogia que pode ajudar alguns leitores.
::
funciona muito parecido com o separador de diretório do sistema de arquivos '/
', ao pesquisar seu caminho para um programa que você gostaria de executar. Considerar:Isso é muito explícito - apenas um executável no local exato na árvore do sistema de arquivos pode corresponder a essa especificação, independentemente do PATH em vigor. Similarmente...
... é igualmente explícito no espaço para nome C ++ "árvore".
Contrastando com esses caminhos absolutos, você pode configurar boas shells do UNIX (por exemplo, zsh ) para resolver caminhos relativos no diretório atual ou em qualquer elemento da
PATH
variável de ambiente, por issoPATH=/usr/bin:/usr/local/bin
, se você estiver dentro/tmp
, então ...... seria executado feliz
/tmp/X11/xterm
se encontrado, mais/usr/bin/X11/xterm
, mais/usr/local/bin/X11/xterm
. Da mesma forma, digamos que você estava em um espaço para nome chamadoX
e teve um "using namespace Y
" efeito, então ...... pode ser encontrada em qualquer um
::X::std::cout
,::std::cout
,::Y::std::cout
, e possivelmente outros lugares devido à pesquisa dependentes do argumento (ADL, também conhecido como Koenig lookup). Portanto, apenas::std::cout
é realmente explícito exatamente exatamente qual objeto você quer dizer, mas felizmente ninguém em seu perfeito juízo jamais criaria sua própria classe / estrutura ou espaço de nome chamado "std
", nem qualquer coisa chamada "cout
", portanto, na prática, usar apenasstd::cout
está bem.Diferenças notáveis :
1) shells tendem a usar a primeira correspondência usando a ordem de entrada
PATH
, enquanto o C ++ gera um erro de compilador quando você é ambíguo.2) No C ++, nomes sem nenhum escopo à frente podem ser correspondidos no namespace atual, enquanto a maioria dos shells do UNIX só fazem isso se você inserir
.
oPATH
.3) O C ++ sempre pesquisa no espaço para nome global (como ter
/
implicitamente o seuPATH
).Discussão geral sobre namespaces e explicitação de símbolos
::abc::def::...
Às vezes, o uso de "caminhos" absolutos pode ser útil para isolá-lo de qualquer outro espaço de nome que você esteja usando, parte de, mas realmente não tem controle sobre o conteúdo ou mesmo outras bibliotecas que o código de cliente da sua biblioteca também usa. Por outro lado, também o acopla mais firmemente ao local "absoluto" existente do símbolo e você perde as vantagens da correspondência implícita nos espaços para nome: menos acoplamento, mobilidade mais fácil do código entre espaços para nome e código-fonte legível e conciso .Como em muitas coisas, é um ato de equilíbrio. Os puts lotes C ++ padrão dos identificadores sob
std::
que são menos "único" do quecout
, que os programadores podem usar para algo completamente diferente no seu código (por exemplomerge
,includes
,fill
,generate
,exchange
,queue
,toupper
,max
). Duas bibliotecas não-padrão não relacionadas têm uma chance muito maior de usar os mesmos identificadores, já que os autores geralmente não têm ou menos consciência um do outro. E as bibliotecas - incluindo a biblioteca C ++ Standard - alteram seus símbolos ao longo do tempo. Tudo isso potencialmente cria ambiguidade ao recompilar o código antigo, principalmente quando há um uso pesado deusing namespace
s: a pior coisa que você pode fazer nesse espaço é permitirusing namespace
s nos cabeçalhos para escapar do escopo dos cabeçalhos, de forma que uma quantidade arbitrariamente grande de código de cliente direto e indireto não consiga tomar suas próprias decisões sobre quais namespaces usar e como gerenciar ambiguidades.Portanto, um líder
::
é uma ferramenta na caixa de ferramentas do programador C ++ para desambiguar ativamente um conflito conhecido e / ou eliminar a possibilidade de ambiguidade futura.fonte
::
é o operador de resolução do escopo. É usado para especificar o escopo de algo.Por exemplo,
::
sozinho é o escopo global, fora de todos os outros namespaces.some::thing
pode ser interpretado de qualquer uma das seguintes maneiras:some
é um espaço para nome (no escopo global, ou um escopo externo que o atual) ething
é um tipo , uma função , um objeto ou um espaço para nome aninhado ;some
é uma classe disponível no escopo atual ething
é um objeto membro , função ou tipo dasome
classe;some
pode ser um tipo base do tipo atual (ou o próprio tipo atual) ething
é um membro dessa classe, um tipo , função ou objeto .Você também pode ter escopo aninhado, como em
some::thing::bad
. Aqui cada nome pode ser um tipo, um objeto ou um espaço para nome. Além disso, o últimobad
,, também pode ser uma função. Os outros não, porque as funções não podem expor nada dentro de seu escopo interno.Portanto, voltando ao seu exemplo,
::thing
pode haver apenas algo no escopo global: um tipo, uma função, um objeto ou um espaço para nome.A maneira como você o usa sugere (usado em uma declaração de ponteiro) que é um tipo no escopo global.
Espero que esta resposta seja completa e correta o suficiente para ajudá-lo a entender a resolução do escopo.
fonte
class some { protected: int thing; }; class some_ext : public some { float thing; void action(){ some::thing = 42; thing = 666; } };
Aquisome
está uma classe base desome_ext
e quando você escrevesome::thing
em funções-membro de some_ext, significa othing
objeto no tipo basesome
. Semsome::
,thing
sozinho significa o que estáthing
no escopo mais próximosome_ext::thing
. Está mais claro?::
é usado para vincular algo (uma variável, uma função, uma classe, um typedef etc ...) a um espaço para nome ou a uma classe.se não houver lado esquerdo antes
::
, sublinha o fato de que você está usando o espaço para nome global.por exemplo:
::doMyGlobalFunction();
fonte
seu chamado operador de resolução de escopo, Um nome global oculto pode ser referido usando o operador de resolução de escopo:
Por exemplo;
fonte
(Essa resposta é principalmente para os googlers, porque o OP já resolveu seu problema.) O significado de prefixado
::
- operador de resolução de escopo - foi descrito em outras respostas, mas eu gostaria de acrescentar por que as pessoas o estão usando.O significado é "pegue o nome do espaço para nome global, e não mais nada". Mas por que isso precisaria ser escrito explicitamente?
Caso de uso - conflito de namespace
Quando você tem o mesmo nome no namespace global e no namespace local / aninhado, o local será usado. Portanto, se você quiser o global, acrescente-o com
::
. Este caso foi descrito na resposta de Wyatt Anderson, veja seu exemplo.Caso de uso - enfatizar função não membro
Quando você está escrevendo uma função de membro (um método), as chamadas para outra função de membro e as chamadas para funções de não membro (gratuitas) são parecidas:
Mas pode acontecer que
Twist
seja uma função irmã da classeA
eBend
seja uma função livre. Ou seja,Twist
pode usar e modificarm_couner
eBend
não pode. Portanto, se você deseja garantir quem_counter
permaneça 0, você precisa verificarTwist
, mas não precisa verificarBend
.Portanto, para tornar isso mais claro, é possível escrever
this->Twist
para mostrar ao leitor queTwist
é uma função membro ou escrever::Bend
para mostrar queBend
é gratuito. Ou ambos. Isso é muito útil quando você está fazendo ou planejando uma refatoração.fonte
::
é um operador de definição do espaço para nome.Por exemplo, se você deseja usar o cout sem mencionar
using namespace std;
no seu código, escreva isto:Quando nenhum espaço para nome é mencionado, é dito que a classe pertence ao espaço para nome global.
fonte
"::" representa o operador de resolução do escopo. Funções / métodos com o mesmo nome podem ser definidos em duas classes diferentes. Para acessar os métodos de um operador de resolução de escopo de classe específico, é usado.
fonte