Qual é o ponto em falta funções em C ++ 11?
-
05-07-2019 - |
Pergunta
C ++ 11 adiciona a capacidade para dizer ao compilador para criar um implementação padrão de qualquer um dos . Embora eu possa ver o valor de apagar uma função, onde está o valor de incumprimento explicitamente uma função? Basta deixá-lo em branco e o compilador irá fazê-lo de qualquer maneira.
O único ponto que eu posso ver é que um construtor padrão só é criado quando existe nenhum outro construtor:
class eg {
public:
eg(int i);
eg() = default;
};
Mas isso é realmente melhor do que como fazê-lo agora?
class eg {
public:
eg(int i);
eg() {}
};
Ou estou faltando um caso de uso?
Solução
A inadimplentes construtor terá uma declaração, e que a declaração será sujeito às regras de acesso normais. Por exemplo. você pode fazer o construtor de cópia padrão protegido. Sem estas novas declarações, os membros padrão gerado são públicos.
Outras dicas
Esses exemplos de de Stroustrup website pode ajudar você a entender o ponto:
inadimplentes e excluídos funções - controle de padrões
O idioma comum de "proibição copiando" agora pode ser expressa diretamente:
class X { // ... X& operator=(const X&) = delete; // Disallow copying X(const X&) = delete; };
Por outro lado, podemos também dizer explicitamente que queremos para o padrão de comportamento de cópia:
class Y { // ... Y& operator=(const Y&) = default; // default copy semantics Y(const Y&) = default; };
Ser explícito sobre o padrão é obviamente redundante, mas comentários a o efeito e (pior) um usuário definir explicitamente operações de cópia destina-se a dar o comportamento padrão são não é incomum. Deixando-o para a compilador para implementar o padrão comportamento é mais simples, menos propensa a erro, e muitas vezes leva a uma melhor código de objeto. O mecanismo de "default" pode ser usado para qualquer função que tem um padrão. O mecanismo de "delete" pode ser usado para qualquer função. Por exemplo, nós podemos eliminar uma conversão indesejada como isto:
struct Z { // ... Z(long long); // can initialize with an long long Z(long) = delete; // but not anything less };
Além de mudar a acessibilidade (privado / protegido) de funções geradas, você será capaz de fazê-los virtual.
struct S
{
virtual ~S();
virtual S& operator=(const S&);
};
S::~S() = default;
S& S::operator=(const S&) = default;
Os seguintes aspectos das funções inadimplentes podem ser modificados:
- Acesso (ser feita não-público)
- virtual
- explícitos (construtores)
- especificações de exceção
- const-ness de parâmetros
mas a fazê-lo, as funções devem ser definidas fora da classe (8.4.2 / 2 no 0x Comissão ++ C final Draft ).
A versão da proposta original de Lawrence Crowl é aqui .
Graças à Roger Pate para o esclarecimento e citação.
1) destruidores Implicitamente gerados não são actualmente virtual. Então, você precisa defini-los, a fim de torná-los virtual, caso em que eles não são tão eficientes. Com = padrão, você terá tanto virtual e eficiente como destruidores gerados implicitamente.
2) Eles terão especificadores de acesso, ao contrário aqueles gerados implicitamente.
3) Se você in-line o seu construtor incumprimento, sua classe ainda permanecem trivial.
Eu suspeito que a possibilidade de default gerar o construtor de cópia será realmente útil. Eu não posso ver um uso para default gerar o construtor padrão desde como você diz a implementação você digita seria mais curto.
Veja Item 17 do grande livro de Scott Meyer " eficaz Modern C ++ " . Ele descreve muitas condições em que padrão de cópia construtores, operações de cópia e operações de movimentação são gerados (ou não gerado).
Em outras palavras, o compilador pode não "fazê-lo de qualquer maneira". Mas se a função especial membro padrão faz sentido, o usuário poderia usar a palavra "default" para explicitamente dizer ao compilador para gerar uma função padrão que de outra forma não ser gerado.
A partir das Coisas para lembrar ao final do Item 17:
operações Mover são gerados somente para as classes carentes operações de movimentação explicitamente declarados, operações de cópia, ou um destruidor.
O construtor de cópia é gerado apenas para as classes faltando um construtor de cópia declarado explicitamente, e está excluída se uma operação de movimentação é declarada. O operador de atribuição de cópia é gerado apenas para as classes falta um operador de atribuição de cópia declarado explicitamente, e está excluída se uma operação de movimentação é declarada. Geração das operações de cópia de classes com um destrutor explicitamente declarado é obsoleto.
Para mim é o recurso de desativação que será útil, para a maioria das classes I atualmente criar I disable cópia & atribuição - será bom ter uma característica que o compilador pode reconhecer de fazer isso, em vez de depender de erros de vinculador .
Inadimplente é mais útil para a cópia-construtores, se você tem uma classe com muitos atributos. Por exemplo, se você tem essa classe:
class MyClass {
private:
int offset;
std::string name;
std::vector<Person*> relatives;
float weight;
MyClass* spouse;
Vehicle* car;
double houseArea;
Date birth;
Person* parents[2];
public:
/* Default constructor will be defined here */
};
em vez de definir a cópia-construtor desta maneira:
MyClass(const MyClass& that) :
offset(that.offset),
name(that.name),
relatives(that.relatives),
weight(that.weight),
spouse(that.spouse),
car(that.car),
houseArea(that.houseArea),
birth(that.birth),
parents(that.parents)
{}
você definiria da seguinte maneira:
MyClass(const MyClass&) = default;