Pergunta

Estou um pouco confuso sobre o porquê eu tenho dito para retornar foo const de um operador binário em c ++ em vez de apenas foo.

Eu estive lendo "Pensando em C ++" de Bruce Eckel e no capítulo sobre a sobrecarga de operadores, ele diz que "fazendo o valor de retorno [de um operador binário sobrecarga] const, você estado que só um const função de membro pode ser chamado para esse valor de retorno. Este é const-correta, porque o impede de armazenar informação potencialmente valiosa em um objeto que será mais provável ser perdido".

No entanto, se eu tiver um operador mais que os retornos const, e um operador de incremento de prefixo, este código é inválido:

class Integer{
int i;

public:
    Integer(int ii): i(ii){ }
    Integer(Integer&);

    const Integer operator+();
    Integer operator++();
};


int main(){

Integer a(0);
Integer b(1);

Integer c( ++(a + b));
}

Para permitir que este tipo de atribuição, não faria sentido ter o operador + retornar um valor não-const? Isso poderia ser feito através da adição de const_casts, mas isso fica bastante volumoso, não é?

Obrigado!

Foi útil?

Solução

Quando você diz ++ x, você está dizendo "adicionar 1 a x, armazenar parte de trás resultado em x, e diga-me o que era". Este é o operador de pré-incremento. Mas, em ++ (a + b), como você é suposto para "armazenar parte de trás resultado em a + b"?

Certamente você pode armazenar a parte de trás resultado na temporário, que está ocupando o resultado de a + b, que desapareceria em breve. Mas se você realmente não me importo onde o resultado foi armazenado, por que você incrementa-lo em vez de apenas adicionar um?

Outras dicas

FYI, ++(a + b) é ilegal mesmo com vagens (tipos de dados antigos simples, como int). Portanto, faz sentido para não permitir-lo para seus próprios tipos de classe também. Tente isto:

int a = 1;
int b = 2;
int c = ++(a+b);

CCG retornos error: lvalue required as increment operand.

No seu caso, seria preferível fazer o seu construtor de cópia ter um argumento const Integer, e criar seu Integer c como este em vez disso:

Integer c(a + b + Integer(1));

Copiar construtores tomam geralmente um const referência, resolver esse problema para você.

(Ter ctor cópia não-const implica alguma transferência de recursos, que pode ser, por vezes, útil, mas para 99% de todas as situações, não é necessário)

Eu acredito que o exemplo do OP seria adequado para a questão se o operador de adição é substituído com qualquer outro operador binário que retorna uma referência, por exemplo, um operador de atribuição:

Integer c( ++(a = b));

Eu vim aqui me perguntando se eu deveria fazer o meu operador de atribuição retorna um const ou uma referência não-const. alguns tutoriais usar versões não-const, ao contrário do "pensando em C ++" 's conselhos. E algumas outras referências dão raciocínio por trás disso:

Observe que a referência retornado não é declarado const. Isso pode ser um pouco confuso, porque ele permite que você escreva coisas loucas como esta:

MyClass a, b, c;

...

(a = b) = C; // O que ??

À primeira vista, você pode querer evitar situações como esta, por ter operator = retornar uma referência const. No entanto, declarações como isso vai funcionar com tipos primitivos. E, pior ainda, algumas ferramentas realmente contar com esse comportamento. Portanto, é importante para retornar uma referência não-const de seus = operador. A regra de ouro é: "Se é bom o suficiente para ints, é bom o suficiente para tipos de dados definidos pelo usuário."

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top