Скопируйте списки инициализации конструктора

Просто переопределяют поля first_name и last_name , как показано ниже, и делают их пустыми = True, пустыми = True

CustomUser(AbstractUser):
     first_name= models.CharField(null=True, blank=True, max_length=100)
     last_name = models.CharField(null=True, blank=True, max_length=100)
     .........
     .........
17
задан Derek 17 April 2009 в 00:22
поделиться

7 ответов

Явно определенные конструкторы копирования не вызывают конструкторы копирования для членов.

При вводе тела конструктор, каждый член этого класса будет инициализирован. То есть, как только вы доберетесь до {, вам гарантируется, что все ваши члены были инициализированы.

Если не указано, члены инициализируются по умолчанию в порядке их появления в классе. (И если они не могут быть, программа плохо сформирована.) Так что, если вы определяете свой собственный конструктор копирования, теперь вы можете вызывать любые конструкторы копирования членов по желанию.

Вот небольшая программа, которую вы можете скопируйте-вставьте куда-нибудь и возитесь с:

#include <iostream>

class Foo {
public:
    Foo() {
        std::cout << "In Foo::Foo()" << std::endl;
    }

    Foo(const Foo& rhs) {
        std::cout << "In Foo::Foo(const Foo&)" << std::endl;
    }
};

class Bar {
public:
    Bar() {
        std::cout << "In Bar::Bar()" << std::endl;
    }

    Bar(const Bar& rhs) {
        std::cout << "In Bar::Bar(const Bar&)" << std::endl;
    }
};

class Baz {
public:
    Foo foo;
    Bar bar;

    Baz() {
        std::cout << "In Baz::Baz()" << std::endl;
    }

    Baz(const Baz& rhs) {
        std::cout << "In Baz::Baz(const Baz&)" << std::endl;
    }
};

int main() {
    Baz baz1;
    std::cout << "Copying..." << std::endl;
    Baz baz2(baz1);
}

Как есть, это печатает:

In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo()
In Bar::Bar()
In Baz::Baz(const Baz&)

Обратите внимание, что по умолчанию инициализируются члены Baz .

Закомментировав явный конструктор копирования, подобно:

/*
Baz(const Baz& rhs) {
    std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
*/

Вывод будет следующим:

In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo(const Foo&)
In Bar::Bar(const Bar&)

Он вызывает конструктор копирования в обоих случаях.

И если мы вновь введем конструктор копирования [Baz и явно скопируем один элемент:

Baz(const Baz& rhs) :
    foo(rhs.foo)
{
    std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}

Мы get:

In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo(const Foo&)
In Bar::Bar()
In Baz::Baz(const Baz&)

Как видите, как только вы явно объявите конструктор копирования , вы отвечаете за копирование всех членов класса; теперь это ваш конструктор.

Это относится ко всем конструкторам, включая конструкторы перемещения.

26
ответ дан 30 November 2019 в 12:01
поделиться

Да. Которы есть корты.

2
ответ дан 30 November 2019 в 12:01
поделиться

Для любой переменной-члена, имеющей конструктор по умолчанию, этот конструктор по умолчанию вызывается, если вы явно не добавили какой-либо другой вызов конструктора для этой переменной-члена в список инициализации.

2
ответ дан 30 November 2019 в 12:01
поделиться

For details see: Is there an implicit default constructor in C++?

Short:

  • Compiler Generated "Default Constructor": uses the default constructor of each member.
  • Compiler Generated "Copy Constructor": uses the copy constructor of each member.
  • Compiler Generated "Assignment Operator": uses the assignment operator of each member.
2
ответ дан 30 November 2019 в 12:01
поделиться

There is nothing magical about a copy constructor, other than that the compiler will add it in if needed. But in how it actually runs, there is nothing special - if you don't explicitly say "use such and such a constructor", it'll use the default.

1
ответ дан 30 November 2019 в 12:01
поделиться

Not in VC9. Not sure about the others.

// compiled as: cl /EHsc contest.cpp
//
//    Output was:
//    Child1()
//    -----
//    Child1()
//    Child2()
//    Parent()
//    -----
//    Child1(Child1&)
//    Child2()
//    Parent(Parent&)

#include <cstdio>

class Child1 {
    int x;
public:
    static Child1 DEFAULT;

    Child1(){
        x = 0;
        printf("Child1()\n");
    }

    Child1(Child1 &other){
        x = other.x;
        printf("Child1(Child1&)\n");
    }
};

Child1 Child1::DEFAULT;

class Child2 {
    int x;
public:
    Child2(){
        x = 0;
        printf("Child2()\n");
    }

    Child2(Child2 &other){
        x = other.x;
        printf("Child2(Child2&)\n");
    }
};

class Parent {
    int x;
    Child1 c1;
    Child2 c2;

public:
    Parent(){
        printf("Parent()\n");
    }

    Parent(Parent &other) : c1(Child1::DEFAULT) {
        printf("Parent(Parent&)\n");
    }
};

int main(){
    printf("-----\n");
    Parent p1;
    printf("-----\n");
    Parent p2(p1);

    return 0;
}
1
ответ дан 30 November 2019 в 12:01
поделиться

Когда компилятор предоставляет cctor по умолчанию, что, по вашему мнению, компилятор делает для переменных-членов? Он копирует, создает it.

В том же духе, если cctor определен пользователем и если пропущено несколько членов, эти члены нельзя оставлять неинициализированными. Инварианты класса устанавливаются во время строительства и должны постоянно поддерживаться. Итак, компилятор сделает это за вас.

0
ответ дан 30 November 2019 в 12:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: