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?

Foi útil?

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.

Aqui está um artigo elaboração deste novo recurso.

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;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top